2017-10-14 13 views
0

私は2つのstructsしか持っていません。私はプロトコルを共有しているので、2つのタイプの間でキャストしようとしていますが、ランタイムエラーが発生します。プロトコルのみを使用して型間をキャストしますか?

これは私がやろうとしているものです:

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). 

私は数百万レコードを持っている場合、私はドンので、これは本当がっかりです」手動で1つずつ変換するためにそれぞれをループする必要があります。各1をループせずに境界の間でオブジェクトを渡すために

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

いかなるパフォーマンスを意識した方法:私は、暗黙的にこのように魔法のようにキャストすることを望んでいましたか?

+0

プロトコルでは、両方のタイプがプロトコル要件を実装していることだけが保証されているため、これを行うことはできません。両方のタイプが互換性があることを保証するものではありません。ところで、Swiftはループを避けるために 'map'のような関数を提供しています(フレームワークはフードの下でループを使います)。 – vadian

答えて

0

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 to Entityに変更すると、値がメモリに作成された方法(someFun()という関数へのアクセスなし)が変更されず、毎回クラッシュします。

関連する問題