gpt4 book ai didi

Swift:使具有相同 "shape"的两种类型符合通用协议(protocol)

转载 作者:行者123 更新时间:2023-12-05 03:44:50 24 4
gpt4 key购买 nike

我有两种不同的类型,它们表示相同的数据,并且具有完全相同的“形状”。这两种不同的类型是代码生成的,我不得不处理它们。但是,我想让它们符合一个共同的协议(protocol),这样我就可以对这两种类型一视同仁。这是一个例子:

假设这是我的两个代码生成类型,我坚持使用它们:

struct User1 {
var email: String
var name: Name

struct Name {
var givenName: String
var familyName: String
}
}

struct User2 {
var email: String
var name: Name

struct Name {
var givenName: String
var familyName: String
}
}

我希望能够互换使用这些类型,因此我创建了一些它们可以遵守的协议(protocol):

protocol NameRepresenting {
var givenName: String { get }
var familyName: String { get }
}

protocol UserRepresenting {
var email: String { get }
var name: NameRepresenting { get }
}

然后我试图让它们符合:

extension User1.Name: NameRepresenting {}
// Error: Type 'User1' does not conform to protocol 'UserRepresenting'
extension User1: UserRepresenting {}

extension User2.Name: NameRepresenting {}
// Error: Type 'User2' does not conform to protocol 'UserRepresenting'
extension User2: UserRepresenting {}

我希望上面的方法可以工作,但是编译失败并出现上面评论的错误。有什么优雅的方法可以使这两种类型符合通用协议(protocol),以便我可以互换使用它们吗?

最佳答案

生成的结构的name 属性的类型为Name,而不是协议(protocol)要求的NameRepresenting。 Swift 目前还不支持协变返回:(

您可以做的是添加关联类型要求:

protocol UserRepresenting {
associatedtype Name : NameRepresenting
var email: String { get }
var name: Name { get }
}

这要求符合者具有符合 NameRepresenting 的类型,并且是 name 属性的类型。

但是,既然它有关联类型要求,您就不能使用 UserRepresenting 作为变量/函数参数的类型。您只能在通用约束中使用它。所以如果你有一个接受UserRepresenting的函数,你需要这样写:

func someFunction<UserType: UserRepresenting>(user: UserType) {

}

如果您的类/结构之一需要存储 UserRepresenting 类型的属性,您也需要使您的类/结构通用:

class Foo<UserType: UserRepresenting> {
var someUser: UserType?
}

这可能适用于您的情况,也可能不适用。如果没有,您可以编写类型橡皮擦:

struct AnyUserRepresenting : UserRepresenting {
var email: String
var name: Name
struct Name : NameRepresenting {
var givenName: String
var familyName: String
}

init<UserType: UserRepresenting>(_ userRepresenting: UserType) {
self.name = Name(
givenName: userRepresenting.name.givenName,
familyName: userRepresenting.name.familyName)
self.email = userRepresenting.email
}
}

现在您可以将任何 UserRepresenting 转换为此 AnyUserRepresenting,并改为使用 AnyUserRepresenting

关于Swift:使具有相同 "shape"的两种类型符合通用协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66220761/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com