Swift 允许协议(protocol)属性和具有不相关类型属性的符合对象之间的名称冲突

标签 swift swift4

发现了一个场景,我预计会发生名称和/或类型冲突,但它会以某种方式通过并编译。

当协议(protocol)的版本具有在扩展中定义的默认值并且对象通过(不相关的)扩展符合协议(protocol)时,具有某些属性的对象可以符合具有相同名称和不同类型的属性的协议(protocol)。

请看下面的例子:

import Foundation

protocol SomeProtocol {
    var someProperty: Int { get }
}

extension SomeProtocol {
    var someProperty: Int { return 3 }
}

struct Thing {
    var someProperty = "string cheese"
}

extension Thing: SomeProtocol {}

let thing = Thing()

print(thing.someProperty) // string cheese
print(thing.someProperty as Int) // 3

请注意,在 Swift 中重载属性通常会导致编译时错误:

class Thing {
    var what: Int { return 3 }
    var what: String { return "three" }
}

错误内容如下:

**Untitled 8.swift:4:6: note: 'what' previously declared here
        var what: Int { return 3 }**

很明显它表现为一个重载函数,但这种行为似乎不是故意的。

向 bugs.swift.org 提交了一张票,但将其写在此处以分享发现并查明我是否遗漏了任何内容或做出了任何有缺陷的假设。

最佳答案

实际上,这看起来像是基于属性的重载。基本上 Swift 允许这样的事情:

func compute() -> Int {
    return 42
}

func compute() -> String {
    return "Answer to the Ultimate Question of Life, the Universe, and Everything"
}

可以这样调用:

let number = compute() as Int // 42
let string = compute() as String // "Answer to the Ultimate Question of Life, the Universe, and Everything"

现在,上述情况对于存储属性是不可能的,因为您只能有一个存储名称,但是在协议(protocol)扩展中该属性是计算出来的,因此它不违反存储规则。

关于Swift 允许协议(protocol)属性和具有不相关类型属性的符合对象之间的名称冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54373010/

相关文章:

image-processing - 使用 Swift 4 在 Metal Compute Kernel 中传递参数

view - 如何: bring view to front on tap; set max/min pinch gesture scale; set screen limit to pan gesture

ios - 向 tableview 添加动画后应用程序崩溃 (Swift)

swift - 将数字签名添加到 PDF Swift

ios - 在网络请求和离线使用方面优化 iOS 应用程序

swift - 从未出现在 View 中的子类创建按钮

Swift 泛型延期问题

ios - iOS10 的 uiView 在 ViewController 内错位,但 iOS11 则不然

ios - 使用 CATransition self.dismiss 时隐藏黑色淡入淡出

ios - 检查 iPhone Swift 4 中的耳机端口是否可用