以下代码:
protocol SomeProtocol { typealias SomeType = Int // used typealias-assignment func someFunc(someVar: SomeType) } class SomeClass: SomeProtocol { func someFunc(someVar: SomeType) { print(someVar) } }
给出编译时错误:
Use of undeclared type ‘SomeType’
添加,比如typealias SomeType = Double,SomeClass解决了错误.
问题是,虽然协议关联类型声明的typealias-assignment部分(可选btw)有什么意义?
在这种情况下,Int到类型的赋值等于没有赋值,因为它被符合类型覆盖:
// this declaration is equal since you HAVE TO provide the type for SomeType protocol SomeProtocol { typealias SomeType func someFunc(someVar: SomeType) }
这样的赋值为SomeType提供了一个默认类型,它被SomeClass中的实现覆盖,但它对协议扩展特别有用:
protocol Returnable { typealias T = Int // T is by default of type Int func returnValue(value: T) -> T } extension Returnable { func returnValue(value: T) -> T { return value } } struct AStruct: Returnable {} AStruct().returnValue(3) // default signature: Int -> Int
只有通过符合协议而不指定T的类型才能免费获得该函数.如果要设置自己的类型,请在结构体中设置写入类型T = String //或任何其他类型.
有关提供的代码示例的一些其他说明
您解决了这个问题,因为您明确了该参数的类型. Swift还会推断您使用过的类型:
class SomeClass: SomeProtocol { func someFunc(someVar: Double) { print(someVar) } }
所以协议的SomeType被推断为Double.
另一个例子,你可以看到类声明中的SomeType没有引用协议:
class SomeClass: SomeProtocol { typealias Some = Int func someFunc(someVar: Some) { print(someVar) } } // check the type of SomeType of the protocol // dynamicType returns the current type and SomeType is a property of it SomeClass().dynamicType.SomeType.self // Int.Type // SomeType gets inferred form the function signature
但是,如果你这样做:
protocol SomeProtocol { typealias SomeType: SomeProtocol func someFunc(someVar: SomeType) }
SomeType必须是SomeProtocol类型,可以用于更明确的抽象和更多的静态代码,而这:
protocol SomeProtocol { func someFunc(someVar: SomeProtocol) }
将动态调度.