gpt4 book ai didi

swift - 仅使用协议(protocol)在类型之间进行转换?

转载 作者:行者123 更新时间:2023-11-30 12:05:16 24 4
gpt4 key购买 nike

我有 2 个仅通过协议(protocol)相关的结构。我尝试在两种类型之间进行转换,因为它们共享一个协议(protocol),但出现运行时错误。

这就是我正在尝试做的事情:

protocol A {
var id: String { get }
var name: String { get }
var isActive: Bool { get set }
}

struct Entity: A {
let id: String
var name: String
var isActive: Bool

func someFun() {
print("\(name), active: \(isActive)")
}
}

struct ViewModel: A {
let id: String
var name: String
var isActive: Bool
}

let vm = ViewModel(id: "abc", name: "John Doe", isActive: true)
let pt = vm as A
let et = pt as! Entity
print(et.someFun()) //crash

我得到的错误是:

Could not cast value of type '__lldb_expr_87.ViewModel' (0x111835638) to '__lldb_expr_87.Entity' (0x111835550).

这真是令人沮丧,因为如果我有数百万条记录,我不想遍历每一条记录来手动逐条转换。我希望像这样隐式施放魔法:

let entity = vm as A as Entity
let entities = vms as [A] as [Entity]

是否有任何注重性能的方法可以在边界之间传递对象而不循环遍历每个对象?

最佳答案

正如 vadian 在他的评论中所说,你不能像这样进行类型转换。要通过类型转换执行您尝试执行的操作,您需要执行以下操作:

let entity = Entity(id: vm.id, name: vm.name, isActive: vm.isActive)

let entities = vms.map {
return Entity(id: $0.id, name: $0.name, isActive: $0.isActive
}

崩溃的原因是类型转换不会更改对象实际拥有的属性和方法,而只会更改它们可以访问的方法和属性。如果执行以下操作,您将无法访问 someFun() 方法:

let entityAsA = Entity(id: "id", name: "name", isActive: true) as A

但是,以下内容将编译并运行而不会崩溃:

(entityAsA as! Entity).someFun()

因此,当您尝试从 ViewModel 转换为 A 到 Entity 时,它不会改变在内存中创建值的方式(无需访问名为 someFun() 的函数),并且每次都会崩溃。

关于swift - 仅使用协议(protocol)在类型之间进行转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46745417/

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