swift - 在 Swift 中将抽象类型转换为具体类型

标签 swift generics type-erasure swift-protocols associated-types

我正在尝试为我的应用制作数据模型。这是场景:

我的应用程序有包含客户信息的客户模型,还包含他/她的付款来源。 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 给我以下描述的错误:

Using 'PaymentSource' as a concrete type conforming to protocol 'PaymentSource' is not supported

我哪里做错了?

最佳答案

swift 是 statically typed language .这意味着必须在编译时知道变量的类型。

当我遇到这个问题时,我是这样解决的

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
}

关于swift - 在 Swift 中将抽象类型转换为具体类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43363876/

相关文章:

haskell - haskell 会删除类型吗?

swift - 如何避免重写父类(super class)初始值设定项

ios - Swift NSDateFormatter 的正确格式

Java泛型和反射: class loading

java - 使用 ParameterizedTypeReference 为 HttpRequestExecutingMessageHandler 设置 ExpectedResponseType

map 上的 Scala 类型不匹配错误

Swift View Controller 声明返回 nil

ios - 无法将类型 '__NSCFConstantString' 的值转换为 'NSArray'

c - 使用 _Generic 实现 "safe"数学运算的合理方法?

swift - AnyHashable 作为 AnyEquatable 的替代品