[英]Convert Abstract Type to Concrete Type in Swift
我正在嘗試為我的應用制作數據模型。 這是場景:
我的應用程序具有“客戶模型”,其中包含客戶的信息,還包含他/她的“付款來源”。 API為我提供了兩種付款方式: 卡和銀行帳戶 ,它們具有完全不同的字段。
所以,這是我的問題,我想要一個抽象類型,即PaymentSource,然后在每個PaymentSource中都有一個函數,用於返回轉換為該類型的對象。 我如何進行類型擦除。
我需要將抽象類型放在一個盒子中,並將其用作具體類型(AnyPaymentSource)。
因此,我已完成以下操作:
protocol PaymentSource {
associatedtype Kind
func cast() -> Kind
}
struct AnyPaymentSource<PS: PaymentSource> {
private var paymentSource: PS
init(paymentSource: PS) {
self.paymentSource = paymentSource
}
func cast() -> PS.Kind {
return paymentSource.cast()
}
}
struct Card: PaymentSource {
func cast() -> Card {
return self
}
}
struct BankAccount: PaymentSource {
func cast() -> BankAccount {
return self
}
}
struct Customer {
var firstName: String
var lastName: String
var email: String
var paymentSource : AnyPaymentSource<PaymentSource>
}
但Customer
通過以下說明給我錯誤:
不支持將“ PaymentSource”用作符合協議“ PaymentSource”的具體類型
我在哪里做錯了?
Swift是靜態類型的語言 。 這意味着必須在編譯時知道變量的類型。
當我遇到這個問題時,我解決了這樣的問題
protocol PaymentSource {
associatedtype Kind
func cast() -> Kind
}
struct AnyPaymentSource<PS: PaymentSource> {
private var paymentSource: PS
init(paymentSource: PS) {
self.paymentSource = paymentSource
}
func cast() -> PS.Kind {
return paymentSource.cast()
}
}
struct Card: PaymentSource {
func cast() -> Card {
return self
}
}
struct BankAccount: PaymentSource {
func cast() -> BankAccount {
return self
}
}
struct Customer<T:PaymentSource> {
var firstName: String
var lastName: String
var email: String
var paymentSource : AnyPaymentSource<T>
}
func test(){
let customerWithCard = Customer<Card>(
firstName: "",
lastName: "",
email: "",
paymentSource: AnyPaymentSource(paymentSource: Card())
)
let customerWithBankAccount = Customer<BankAccount>(
firstName: "",
lastName: "",
email: "",
paymentSource: AnyPaymentSource(paymentSource: BankAccount())
)
print(customerWithCard.paymentSource.cast())
print(customerWithBankAccount.paymentSource.cast())
return
}
如果您要實現的目標是@Andrew Ashurov在他的回答中提到的目標,則無需實現AnyPaymentSource
。 如Swift協議文檔中所述 :
協議本身實際上並未實現任何功能。 但是, 您創建的任何協議都將成為可 在您的代碼中使用 的完整類型 。
意味着已經能夠將協議視為類型 。
有可能:
protocol PaymentSource {
func cast() -> Self
}
struct Card: PaymentSource {
func cast() -> Card {
return self
}
}
struct BankAccount: PaymentSource {
func cast() -> BankAccount {
return self
}
}
struct Customer {
var firstName: String
var lastName: String
var email: String
var paymentSource : PaymentSource?
}
創建客戶:
let cardCustomer = Customer(firstName: "Card Fname", lastName: "Card Lname", email: "cardemail@example.com", paymentSource: Card())
let bankAccountCustomer = Customer(firstName: "Bank Account Fname", lastName: "Bank Account Lname", email: "bankaccountemail@example.com", paymentSource: BankAccount())
請注意,在“ Customer
結構中, PaymentSource
類型的paymentSource
屬性意味着可以將其分配為符合PaymentSource
協議的任何類型(在您的情況下為Card
和BankAccount
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.