从协议扩展中调用 class 属性
Calling class properties from within protocol extension
在为默认实现使用协议扩展时我遇到了问题。我定义了一个具有不同可选属性和功能的协议来使用。在扩展中,我实现了一个默认函数和 nil 属性。在实现中,我使用协议中的属性和函数。
在设备上它按我预期的方式工作。同样在调试器上,当我 运行 进入扩展实现中的断点时,它给了我来自 class 的 属性。
谁能帮我解决为什么我没有从 class 中得到示例中的 属性 而从扩展中得到 nil 属性 的原因。
操场上的例子
import UIKit
protocol Collectable {
var item: String? { get }
func collect()
}
extension Collectable {
var item: String? { return nil }
func collect() {
if let some = item {
print("collect \(some)")
} else {
print("nothing")
}
}
}
class Car: Collectable {
var item = "letter"
}
let car = Car()
car.collect()
在协议中,您的项目是可选字符串,而在您的 class 中,您声明了另一个名为项目的变量。您的收集功能正在寻找可选项目,并且在扩展中您指定它应该 return nil.
正如@SavcaMarin 在他们的回答中所述,您在扩展程序 (String?
) 中声明的 item
属性 与 [=13= 中声明的类型之间存在类型冲突] (String
).
如果您评论扩展程序,您可以看到这个。编译器会告诉你Car
不符合Collectable
。如果您要求它创建所需的存根,它将创建 func collect
和 var item: String?
。然后它给出一个错误 item
被重新定义。
正如 Rob 和 Matt 在对另一个答案的评论中指出的那样,这似乎是 Swift 编译器中的一个错误。如果有满足协议一致性的默认实现(您的扩展),它并不表示 item
的重新定义或您的 item
不符合协议。
简单的解决方法是通过显式声明类型(String?
) 而不是依赖类型推断(给出 String
):
class Car: Collectable {
var item:String? = "letter"
}
在为默认实现使用协议扩展时我遇到了问题。我定义了一个具有不同可选属性和功能的协议来使用。在扩展中,我实现了一个默认函数和 nil 属性。在实现中,我使用协议中的属性和函数。
在设备上它按我预期的方式工作。同样在调试器上,当我 运行 进入扩展实现中的断点时,它给了我来自 class 的 属性。
谁能帮我解决为什么我没有从 class 中得到示例中的 属性 而从扩展中得到 nil 属性 的原因。
操场上的例子
import UIKit
protocol Collectable {
var item: String? { get }
func collect()
}
extension Collectable {
var item: String? { return nil }
func collect() {
if let some = item {
print("collect \(some)")
} else {
print("nothing")
}
}
}
class Car: Collectable {
var item = "letter"
}
let car = Car()
car.collect()
在协议中,您的项目是可选字符串,而在您的 class 中,您声明了另一个名为项目的变量。您的收集功能正在寻找可选项目,并且在扩展中您指定它应该 return nil.
正如@SavcaMarin 在他们的回答中所述,您在扩展程序 (String?
) 中声明的 item
属性 与 [=13= 中声明的类型之间存在类型冲突] (String
).
如果您评论扩展程序,您可以看到这个。编译器会告诉你Car
不符合Collectable
。如果您要求它创建所需的存根,它将创建 func collect
和 var item: String?
。然后它给出一个错误 item
被重新定义。
正如 Rob 和 Matt 在对另一个答案的评论中指出的那样,这似乎是 Swift 编译器中的一个错误。如果有满足协议一致性的默认实现(您的扩展),它并不表示 item
的重新定义或您的 item
不符合协议。
简单的解决方法是通过显式声明类型(String?
) 而不是依赖类型推断(给出 String
):
class Car: Collectable {
var item:String? = "letter"
}