swift - 协议(protocol)关联类型类型别名分配编译错误

标签 swift swift2 protocols

以下代码:

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/

相关文章:

ios - 识别是否在模拟器ios9中运行

swift - 禁用 WatchKit TableRow 的选择

swift - Swift 2.2 中 Alamofire 请求的返回值

ios - swift 2.0 - "Argument passed to call that takes no arguments"

带有 slider 的 UITableView 单元格 : touch not working correctly swift 2

Swift 关联类型和协议(protocol)继承

ios - UiStackView 内的 UiTextField 没有响应

ios - 使用多个过滤器从 Firebase 查询数据

swift - swift 中的平等协议(protocol)

tcp - 为什么DNS使用UDP作为传输层协议(protocol)?