考慮一個工廠方法模式實作:
import UIKit
protocol TransportProtocol: CustomStringConvertible {
func techReview()
}
// Make default implemetation opposed to @objc optional methods and properties
extension TransportProtocol {
func techReview() {
print("Reviewing \(type(of: self))")
}
var description: String {
"This is a \(type(of: self))"
}
}
final class Car: TransportProtocol {
func changeOil() {
print("Changed oil")
}
}
final class Ship: TransportProtocol {
}
protocol LogisticProtocol {
associatedtype Transport: TransportProtocol
func createTransport() -> Transport
func delivery(from A: Any, to B: Any)
func techRewiew(for transport: TransportProtocol)
}
extension LogisticProtocol {
func delivery(from A: Any, to B: Any) {
print("Moving \(type(of: self)) from \(A) to \(B)")
}
func techRewiew(for transport: TransportProtocol) {
transport.techReview()
}
}
final class RoadLogistics: LogisticProtocol {
func createTransport() -> some TransportProtocol {
Car()
}
}
final class SeaLogistics: LogisticProtocol {
func createTransport() -> some TransportProtocol {
Ship()
}
}
// Usage:
class Client {
// ...
static func someClientCode<L: LogisticProtocol>(creator: L) -> some TransportProtocol {
let transport = creator.createTransport()
print("I'm not aware of the creator's type, but it still works.\n"
transport.description "\n")
creator.delivery(from: "Source", to: "Destination")
return transport
}
// ...
}
let someTransport = Client.someClientCode(creator: RoadLogistics())
type(of: someTransport.self) // Car
someTransport.changeOil() // Error: Value of type 'some TransportProtocol' has no member 'changeOil'
問題是如果編譯器知道它不僅僅是 a ,為什么我不能呼叫changeOil()。我們可以從使用指令中獲得什么好處,而不僅僅是裸協議型別?someTransportCarTransportProtocolsome
uj5u.com熱心網友回復:
該方法的回傳型別是some TransportProtocol,不是Car。因此,即使回傳的實體是 type Car,您也不能在其上呼叫任何僅存在 onCar而不存在 on 的方法TransportProtocol。
運行時知道someTransportis的具體型別Car,但編譯器只知道回傳型別符合TransportProtocol。
如果您希望能夠訪問Car上的方法someTransport,則需要將其向下轉換為Car.
if let car = someTransport as? Car {
car.changeOil()
}
使用some關鍵字在用于不透明回傳型別時具有型別系統優勢(在SE-0244中作為 Swift 5.1 的一部分引入),因為它實際上可以回傳具有關聯型別的協議,而無需顯式地使方法通用。這就是驅動 SwiftUI 的原因,因為它使您能夠回傳some View.
另一方面,對沒有關聯型別的協議使用不透明回傳型別沒有任何好處,因此在您的特定示例中,沒有理由使用它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/449180.html
