简体   繁体   English

Swift泛型函数无法在测试中编译

[英]Swift generic function does not compile in testing

I have a problem with compiling tests cases in Swift. 我在Swift中编译测试用例时遇到问题。 It looks like the compiler is loosing information about template type but other generic methods are working fine. 看起来编译器正在丢失有关模板类型的信息,但其他通用方法也能正常工作。 What am I missing? 我想念什么?

public class MatchNorm {

    public static func resolve1<T:SequenceType where T.Generator.Element:MatchNormElement>(list: T, lti: LinearTransformation, accuracy: Double) -> LinearTransformation {
        // no problem
        return MatchNorm.resolve1(list, lti: lti, accuracy: accuracy)
    }

    public static func resolve2<T:SequenceType where T.Generator.Element:MatchNormElement>(list: T, lti: LinearTransformation, accuracy: Double) -> LinearTransformation {

        for elem in list {
            print(elem.x)
        }
        return lti
    }
}
public class MatchNormTest: XCTestCase  {
    func testMatchNorm1() {
        var list = [MatchNormElement]()

        // compilation error here!
        let  ll = MatchNorm.resolve1(list, lti: LinearTransformation(1), accuracy: 0.001)
// MatchNormTest.swift:70:29: Cannot invoke 'resolve1' with an argument list of type '([MatchNormElement], lti: LinearTransformation, accuracy: Double)'
// MatchNormTest.swift:70:29: Expected an argument list of type '(T, lti: LinearTransformation, accuracy: Double)'
    }
}

Update 更新资料

MatchNormElement is a protocol, so I changed it to concrete type. MatchNormElement是一个协议,因此我将其更改为具体类型。 Now it works. 现在可以了。

func testMatchNorm1() {
    var list = [Measurment]()

        // works fine
     let  ll = MatchNorm.resolve1(list, lti: LinearTransformation(1), accuracy: 0.001)
}

This is reasonable for the compiler. 这对于编译器是合理的。 Swift allows type conversion for a Concrete type to a Protocol based variable assignment. Swift允许将具体类型的类型转换为基于协议的变量分配。

However, Swift doesnot allow converting a set of Concrete Types to a set/array of Protocol by converting each. 但是,Swift不允许通过转换每个具体类型将一组具体类型转换为一组协议。 This is reasonable because of the following reasons: 这是合理的,因为以下原因:

Let suppose we have this constructs in place: 假设我们具有以下结构:

protocol IntType {}
extension Int: IntType{}

Now lets do the obvious thing: 现在让我们做显而易见的事情:

let item = 12
let item2:IntType = item

Then the one that will look obvious to the eye: This wont compile for good reason. 然后,一个在眼睛上看起来很明显的东西:这不会有充分的理由进行编译。

let a = [1,2,3]
let b: [IntType] = a

Lets inspect the size of each Type before moving ahead: 让我们在继续之前检查每种类型的大小:

sizeofValue(item)   //8
sizeofValue(item2)  //40

An array is a contagious memory of 8 bytes. 数组是具有8个字节的可感染内存。 So is Array a contagious memory of 40 bytes. 因此Array是一个40字节的传染性内存。

When we did this: 当我们这样做时:

let b: [IntType] = a

We essentially tell the compiler to convert 8 bytes of array into 40 bytes of array and store it. 我们实质上告诉编译器将数组的8个字节转换为数组的40个字节并进行存储。 Now as the array is contagious it has to destruct or reshuffle which is expensive task to do so. 现在,由于阵列具有感染力,因此必须销毁或改组,这是一项昂贵的任务。 This hinders the performance and obviously you lose the type safety. 这会妨碍性能,并且显然会丢失类型安全性。

The compiler could this this transformation but Swift team decided for good reason that the user need to be explicit if they want this type transformation for 2 reasons: Performance and Type Safety . 编译器可以进行此转换,但是Swift团队出于充分的理由决定,如果用户想要此类型转换,则需要明确,因为两个原因: PerformanceType Safety

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM