Swift:使用相同的“制造两种类型”;形状“;遵守共同协议
我有两种不同的类型,它们表示相同的数据,并且具有完全相同的“形状”。这两种不同的类型是代码gen'd,我不得不处理它们。但是,我想让它们符合一个通用协议,这样我就可以对这两种类型进行相同的处理。下面是一个例子: 假设这是我的两种代码gen'd类型,我一直在使用:Swift:使用相同的“制造两种类型”;形状“;遵守共同协议,swift,swift-protocols,Swift,Swift Protocols,我有两种不同的类型,它们表示相同的数据,并且具有完全相同的“形状”。这两种不同的类型是代码gen'd,我不得不处理它们。但是,我想让它们符合一个通用协议,这样我就可以对这两种类型进行相同的处理。下面是一个例子: 假设这是我的两种代码gen'd类型,我一直在使用: struct User1 { var email: String var name: Name struct Name { var givenName: String v
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 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 {}
我希望上面的方法能起作用,但是编译失败,上面评论了错误。有没有什么好办法使这两种类型符合通用协议,以便我可以互换使用它们?生成的结构的
name
属性具有typename
,而不是协议要求的name。Swift目前还不支持协变回报:(
您可以做的是添加关联的类型需求:
protocol UserRepresenting {
associatedtype Name : NameRepresenting
var email: String { get }
var name: Name { get }
}
这要求符合项的类型必须符合namefresentation
,并且是name
属性的类型
但是,现在它有一个关联的类型要求,您不能使用userrepresentation
作为变量/函数参数的类型。您只能在泛型约束中使用它。因此,如果您有一个函数采用userrepresentation
,您需要这样编写:
func someFunction<UserType: UserRepresenting>(user: 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
}
}
struct AnyUserRepresenting:UserRepresenting{
var电子邮件:String
变量名称:名称
结构名称:namefresenting{
var givenName:字符串
var familyName:字符串
}
init(uUserRepresentating:UserType){
self.name=名称(
givenName:userrepresentating.name.givenName,
familyName:UserRepresentating.name.familyName)
self.email=userrepresentation.email
}
}
现在,您可以将任何表示
的用户转换为该表示
的任何用户,并改为使用表示
的任何用户
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
}
}