[英]Swift: Store Type of implementation of Protocol in static var of protocol extension
[英]Swift protocol extension `var { get }` override implementation's `let`
當將實現結構分配給類型為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.
這是 Swift 的設計行為嗎?
我認為這是一個編譯器錯誤。 如果您將LetReq
可選字符串,它會按預期工作:
struct LetReq: Req {
let path: String? = "LetReq"
}
向 Apple提交錯誤。
我認為這種行為是正確的。
struct LetReq: Req {
let path = "LetReq"
}
路徑是String
類型不是String?
var req: Req!
req = LetReq()
req.path
req
是Req
類型。 所以req.path
表示類型是String?
名稱是path
Req
的擴展具有path
變量的默認變量。 所以req.path
指的是變量不是LetReq
的path
這很模糊......但我敢打賭一個錯誤。
至少對於當前的實現( swiftc
2.2);
這可以證明這一點。
struct AA {
func a() -> String { return "" }
func a() -> String? { return "" }
var b: String { return "" }
var b: String? { return "" } // Error: Invalid redeclaraion of `b`.
}
但無論如何,編譯器似乎並沒有通過協議擴展來檢查這個重新聲明。 所以, LetReq
實例實際上提供了兩個屬性。
var path: String { get }
var path: String? { get }
你可以用這個來檢查這個。
print(LetReq().path as String?) // prints `Optional("Req")`.
print(LetReq().path as String) // prints `LetReq`.
我相信編譯器必須防止這種屬性重載。 出於同樣的原因,他們阻止了struct AA
屬性重載。 所以,在我看來,這是一個錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.