以下代码:
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
可以解决错误。
问题是,协议(protocol)关联类型声明的typealias-assignment 部分(顺便说一句,它是可选的)有什么意义?
最佳答案
在这种情况下,将 Int
分配给 typealias
等于没有分配,因为它会被您的符合类型覆盖:
// this declaration is equal since you HAVE TO provide the type for SomeType
protocol SomeProtocol {
typealias SomeType
func someFunc(someVar: SomeType)
}
这样的分配为 SomeType
提供了一个默认类型,它会被您在 SomeClass
中的实现覆盖,但它对协议(protocol)扩展特别有用:
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
类型的情况下遵守协议(protocol),您才能免费获得该功能。如果您想设置自己的类型,请在结构体中写入 typealias T = String//或任何其他类型
。
关于提供的代码示例的一些附加说明
你解决了这个问题,因为你明确了参数的类型。 Swift 还会推断您使用的类型:
class SomeClass: SomeProtocol {
func someFunc(someVar: Double) {
print(someVar)
}
}
因此协议(protocol)的SomeType
被推断为Double
。
另一个例子,你可以看到类声明中的 SomeType
没有引用协议(protocol):
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)
}
将被动态调度。
关于swift - 协议(protocol)关联类型类型别名分配编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31562276/