[英]Swift protocol extension `var { get }` override implementation's `let`
Implementing property with var
and let
behaves differently when the implementing struct is assigned to a variable typed as protocol
.当将实现结构分配给类型为
protocol
的变量时,使用var
和let
实现属性的行为会有所不同。
protocol Req {
var path: String? { get }
}
extension Req {
var path: String? { return "Req" }
}
struct LetReq: Req {
let path = "LetReq"
}
struct VarReq: Req {
var path: String? { return "VarReq" }
}
var req: Req!
req = VarReq()
req.path // prints "VarReq"
req = LetReq()
req.path // prints "Req" not "LetReq" which seems very awkward.
Is this designed behaviour of Swift?这是 Swift 的设计行为吗?
I think this is a compiler bug.我认为这是一个编译器错误。 If you make a
LetReq
an optional string, it works as expected:如果您将
LetReq
可选字符串,它会按预期工作:
struct LetReq: Req {
let path: String? = "LetReq"
}
File a bug with Apple.向 Apple提交错误。
I think that behavior is correct.我认为这种行为是正确的。
struct LetReq: Req {
let path = "LetReq"
}
path is String
type not String?
路径是
String
类型不是String?
var req: Req!
req = LetReq()
req.path
req
is type of Req
. req
是Req
类型。 So req.path
means type is String?
所以
req.path
表示类型是String?
and name is path
名称是
path
Req
's extension has default variable for path
variable. Req
的扩展具有path
变量的默认变量。 so req.path
refer that variable not LetReq
's path
所以
req.path
指的是变量不是LetReq
的path
It's vague... But I would bet on a bug.这很模糊......但我敢打赌一个错误。
At least for current implementation( swiftc
2.2);至少对于当前的实现(
swiftc
2.2);
This can be proven by this.这可以证明这一点。
struct AA {
func a() -> String { return "" }
func a() -> String? { return "" }
var b: String { return "" }
var b: String? { return "" } // Error: Invalid redeclaraion of `b`.
}
But anyway, the compiler doesn't seem to check this redeclaration by protocol extension.但无论如何,编译器似乎并没有通过协议扩展来检查这个重新声明。 So,
LetReq
instance actually provides two properties.所以,
LetReq
实例实际上提供了两个属性。
var path: String { get }
var path: String? { get }
You can check this with this.你可以用这个来检查这个。
print(LetReq().path as String?) // prints `Optional("Req")`.
print(LetReq().path as String) // prints `LetReq`.
I believe this kind of property overloading must be prevented by compiler.我相信编译器必须防止这种属性重载。 For same reason of why they prevented property overloading in
struct AA
.出于同样的原因,他们阻止了
struct AA
属性重载。 So, that's a bug in my opinion.所以,在我看来,这是一个错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.