Error[8]: Undefined offset: 4, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述我有一组不同的结构,都实现了Equatable协议,我试图将它传递给一个需要T.Iterator.Element:Equatable集合的函数.我知道如何通过使用类来解决这个问题,只需创建一个类:Vehicle:Identifiable,Equatable,然后使Car和Tractor实现Vehicle.但是,我想知道使用结构和协议是否可行? 这是我正在尝试做的一个人为的例子 //: Playgr 我有一组不同的结构,都实现了Equatable协议,我试图将它传递给一个需要T.Iterator.Element:Equatable集合的函数.我知道如何通过使用类来解决这个问题,只需创建一个类:Vehicle:IDentifiable,Equatable,然后使Car和Tractor实现Vehicle.但是,我想知道使用结构和协议是否可行?

这是我正在尝试做的一个人为的例子

//: Playground - noun: a place where people can playprotocol IDentifiable {    var ID: String { get set }    init(ID: String)    init()}extension IDentifiable {    init(ID: String) {        self.init()        self.ID = ID    }}typealias Vehicle = IDentifiable & Equatablestruct Car: Vehicle {    var ID: String    init() {        ID = ""    }    public static func ==(lhs: Car,rhs: Car) -> Bool {        return lhs.ID == rhs.ID    }}struct Tractor: Vehicle {    var ID: String    init() {        ID = ""    }    public static func ==(lhs: Tractor,rhs: Tractor) -> Bool {        return lhs.ID == rhs.ID    }}class Operator {    func operationOnCollectionOfEquatables<T: Collection>(array: T) where T.Iterator.Element: Equatable {    }}var array = [Vehicle]() //Protocol 'Equatable' can only be used as a generic constraint because Self or associated type requirementsarray.append(Car(ID:"VW"))array.append(Car(ID:"Porsche"))array.append(Tractor(ID:"John Deere"))array.append(Tractor(ID:"Steyr"))var op = Operator()op.operationOnCollectionOfEquatables(array: array) //Generic parameter 'T' Could not be inferred
问题是,正如错误所述,您不能将具有Self或相关类型要求的协议用作实际类型 – 因为您丢失了这些要求的类型信息.在这种情况下,您将丢失==实现的参数的类型信息 – 正如Equatable所说,它们必须与符合类型(即Self)的类型相同.

解决方案几乎总是构建一个type eraser.如果期望类型相等,如果它们的ID属性相等,这可以像存储ID属性并在==实现中进行比较一样简单.

struct AnyVehicle : Equatable {    static func ==(lhs: AnyVehicle,rhs: AnyVehicle) -> Bool {        return lhs.ID == rhs.ID    }    let ID : String    init<T : Vehicle>(_ base: T) {        ID = base.ID    }}

(注意我将您的ID属性重命名为ID以符合Swift命名约定)

但是,更通用的解决方案是在类型擦除器中存储一个函数,它可以在类型转换后根据它们的==实现比较两个任意的车辆符合实例,以确保它们与类型橡皮擦的具体类型相同是用.创建的.

struct AnyVehicle : Equatable {    static func ==(lhs: AnyVehicle,rhs: AnyVehicle) -> Bool {        // forward to both lhs's and rhs's _isEqual in order to determine equality.        // the reason that both must be called is to preserve symmetry for when a        // superclass is being compared with a subclass.        // if you kNow you're always working with value types,you can omit one of them.        return lhs._isEqual(rhs) || rhs._isEqual(lhs)    }    let base: IDentifiable    private let _isEqual: (_ to: AnyVehicle) -> Bool    init<T : Vehicle>(_ base: T) {        self.base = base        _isEqual = {            // attempt to cast the passed instance to the concrete type that            // AnyVehicle was initialised with,returning the result of that            // type's == implementation,or false otherwise.            if let other = 
print(AnyVehicle(Car(ID: "foo")) == AnyVehicle(Tractor(ID: "foo"))) // falseprint(AnyVehicle(Car(ID: "foo")) == AnyVehicle(Car(ID: "bar"))) // falseprint(AnyVehicle(Car(ID: "foo")) == AnyVehicle(Car(ID: "foo"))) // truevar array = [AnyVehicle]()array.append(AnyVehicle(Car(ID: "VW")))array.append(AnyVehicle(Car(ID: "Porsche")))array.append(AnyVehicle(Tractor(ID: "John Deere")))array.append(AnyVehicle(Tractor(ID: "Steyr")))var op = Operator()// compiles fine as AnyVehicle conforms to Equatable.op.operationOnCollectionOfEquatables(array: array)
.base as? T { return base == other } else { return false } } }}
[+++] 总结

以上是内存溢出为你收集整理的arrays – 在实现Equatable的结构数组上的 *** 作全部内容,希望文章能够帮你解决arrays – 在实现Equatable的结构数组上的 *** 作所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
arrays – 在实现Equatable的结构数组上的 *** 作_app_内存溢出

arrays – 在实现Equatable的结构数组上的 *** 作

arrays – 在实现Equatable的结构数组上的 *** 作,第1张

概述我有一组不同的结构,都实现了Equatable协议,我试图将它传递给一个需要T.Iterator.Element:Equatable集合的函数.我知道如何通过使用类来解决这个问题,只需创建一个类:Vehicle:Identifiable,Equatable,然后使Car和Tractor实现Vehicle.但是,我想知道使用结构和协议是否可行? 这是我正在尝试做的一个人为的例子 //: Playgr 我有一组不同的结构,都实现了Equatable协议,我试图将它传递给一个需要T.Iterator.Element:Equatable集合的函数.我知道如何通过使用类来解决这个问题,只需创建一个类:Vehicle:IDentifiable,Equatable,然后使Car和Tractor实现Vehicle.但是,我想知道使用结构和协议是否可行?

这是我正在尝试做的一个人为的例子

//: Playground - noun: a place where people can playprotocol IDentifiable {    var ID: String { get set }    init(ID: String)    init()}extension IDentifiable {    init(ID: String) {        self.init()        self.ID = ID    }}typealias Vehicle = IDentifiable & Equatablestruct Car: Vehicle {    var ID: String    init() {        ID = ""    }    public static func ==(lhs: Car,rhs: Car) -> Bool {        return lhs.ID == rhs.ID    }}struct Tractor: Vehicle {    var ID: String    init() {        ID = ""    }    public static func ==(lhs: Tractor,rhs: Tractor) -> Bool {        return lhs.ID == rhs.ID    }}class Operator {    func operationOnCollectionOfEquatables<T: Collection>(array: T) where T.Iterator.Element: Equatable {    }}var array = [Vehicle]() //Protocol 'Equatable' can only be used as a generic constraint because Self or associated type requirementsarray.append(Car(ID:"VW"))array.append(Car(ID:"Porsche"))array.append(Tractor(ID:"John Deere"))array.append(Tractor(ID:"Steyr"))var op = Operator()op.operationOnCollectionOfEquatables(array: array) //Generic parameter 'T' Could not be inferred
问题是,正如错误所述,您不能将具有Self或相关类型要求的协议用作实际类型 – 因为您丢失了这些要求的类型信息.在这种情况下,您将丢失==实现的参数的类型信息 – 正如Equatable所说,它们必须与符合类型(即Self)的类型相同.

解决方案几乎总是构建一个type eraser.如果期望类型相等,如果它们的ID属性相等,这可以像存储ID属性并在==实现中进行比较一样简单.

struct AnyVehicle : Equatable {    static func ==(lhs: AnyVehicle,rhs: AnyVehicle) -> Bool {        return lhs.ID == rhs.ID    }    let ID : String    init<T : Vehicle>(_ base: T) {        ID = base.ID    }}

(注意我将您的ID属性重命名为ID以符合Swift命名约定)

但是,更通用的解决方案是在类型擦除器中存储一个函数,它可以在类型转换后根据它们的==实现比较两个任意的车辆符合实例,以确保它们与类型橡皮擦的具体类型相同是用.创建的.

struct AnyVehicle : Equatable {    static func ==(lhs: AnyVehicle,rhs: AnyVehicle) -> Bool {        // forward to both lhs's and rhs's _isEqual in order to determine equality.        // the reason that both must be called is to preserve symmetry for when a        // superclass is being compared with a subclass.        // if you kNow you're always working with value types,you can omit one of them.        return lhs._isEqual(rhs) || rhs._isEqual(lhs)    }    let base: IDentifiable    private let _isEqual: (_ to: AnyVehicle) -> Bool    init<T : Vehicle>(_ base: T) {        self.base = base        _isEqual = {            // attempt to cast the passed instance to the concrete type that            // AnyVehicle was initialised with,returning the result of that            // type's == implementation,or false otherwise.            if let other = 
print(AnyVehicle(Car(ID: "foo")) == AnyVehicle(Tractor(ID: "foo"))) // falseprint(AnyVehicle(Car(ID: "foo")) == AnyVehicle(Car(ID: "bar"))) // falseprint(AnyVehicle(Car(ID: "foo")) == AnyVehicle(Car(ID: "foo"))) // truevar array = [AnyVehicle]()array.append(AnyVehicle(Car(ID: "VW")))array.append(AnyVehicle(Car(ID: "Porsche")))array.append(AnyVehicle(Tractor(ID: "John Deere")))array.append(AnyVehicle(Tractor(ID: "Steyr")))var op = Operator()// compiles fine as AnyVehicle conforms to Equatable.op.operationOnCollectionOfEquatables(array: array)
.base as? T { return base == other } else { return false } } }}
总结

以上是内存溢出为你收集整理的arrays – 在实现Equatable的结构数组上的 *** 作全部内容,希望文章能够帮你解决arrays – 在实现Equatable的结构数组上的 *** 作所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1035691.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存