无法调用' methodName'使用类型的参数列表

时间:2016-09-21 17:47:29

标签: swift generics

我无法理解这个编译器的错误信息 "无法调用' getValueType'使用类型'(值:T)'的参数列表 对于该行" if(CMFStream.getValueType(value:test)!= type){"

public func readArray<T>() -> Array<T>
{
    // ...
    var retval: Array<T>;
    let test: T;
    if (CMFStream.getValueType(value: test) != type) {
    // ...
    }
}

我想我不了解泛型和模板之间的区别。

1 个答案:

答案 0 :(得分:3)

您正在将T类型的对象传递给getValueTypeT是一种不受约束的泛型类型,这意味着在编译时它可以是范围中已知的任何类型。它有一个确定的类型,但编译器不知道该类型是什么。 T是占位符。

当遇到使用类型为getValueType的参数调用T的行时,它会寻找满足该条件的方法。你看到的错误说它没有办法做到这一点。

这是一个最小的例子:

func foo<U>(f:U) {
    bar(b:f)
}

func bar(b:Int) {
}

这会失败,因为bar接受一个I​​nt,但foo可以传递任何类型。

有两种方法可以解决这个问题。

方法1

使栏成为通用:

func bar<V>(b:V) {
}

所以如果你打电话

foo(f:1)

编译器将U替换为Int,创建:

func foo(f:Int) {
    bar(b:f)
}

现在它需要一个接受Int的栏,因此它会将V替换为Int以提供

func bar(b:Int) {
}

现在类型是一致的,所以可以继续。

方法2

约束U

protocol P {}

func foo<U:P>(f:U) {
    bar(b:f)
}

这表示U是符合协议P的任何类型。所以现在我们可以像这样定义bar

func bar(b:P) {
}

这定义了bar,它接受​​符合协议P的任何内容。

现在无论占位符U被替换为什么,编译器都知道它符合P,并且总能找到一个bar来接受符合P的内容}。编译器可以继续。