[英]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.