第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在Swift的[String:Class <Protocol>]類型的字典中存儲Class

如何在Swift的[String:Class <Protocol>]類型的字典中存儲Class

炎炎設(shè)計 2019-11-04 13:10:32
我想在[String:SomeClass]類型的Dictionary中存儲一個更專業(yè)的類型。這是一些說明我的問題的示例代碼(也可以在https://swiftlang.ng.bluemix.net/#/repl/579756cf9966ba6275fc794a上使用):class Thing<T> {}protocol Flavor {}class Vanilla: Flavor {}var dict = [String:Thing<Flavor>]()dict["foo"] = Thing<Vanilla>() 它產(chǎn)生錯誤ERROR at line 9, col 28: cannot assign value of type 'Thing<Vanilla>' to type 'Thing<Any>?'。我嘗試過強制轉(zhuǎn)換,Thing<Vanilla>() as Thing<Flavor>但是會產(chǎn)生錯誤cannot convert value of type 'Thing<Vanilla>' to type 'Thing<Flavor>' in coercion。我也嘗試將Dictionary定義為type,[String:Thing<Any>]但這也沒有任何改變。如何在Thing不求助于平原的情況下創(chuàng)建不同s 的集合[String:AnyObject]?我還應(yīng)該提到該類Thing不是我定義的(實際上是關(guān)于BoltsSwift Task的),因此創(chuàng)建Thing沒有類型參數(shù)的基類的解決方案不起作用。
查看完整描述

3 回答

?
皈依舞

TA貢獻1851條經(jīng)驗 獲得超3個贊

A Thing<Vanilla>不是Thing<Flavor>。Thing不是協(xié)變的。Swift中無法表達Thing協(xié)變。這有充分的理由。如果沒有嚴(yán)格的規(guī)則就允許您要求的內(nèi)容,則可以編寫以下代碼:


func addElement(array: inout [Any], object: Any) {

    array.append(object)

}


var intArray: [Int] = [1]

addElement(array: &intArray, object: "Stuff")

Int是的子類型Any,因此如果[Int]是的子類型[Any],則可以使用此函數(shù)將字符串追加到int數(shù)組。這破壞了類型系統(tǒng)。不要那樣做


根據(jù)您的實際情況,有兩種解決方案。如果是值類型,則將其重新打包:


let thing = Thing<Vanilla>(value: Vanilla())

dict["foo"] = Thing(value: thing.value)

如果是參考類型,請在其旁邊加上類型橡皮擦。例如:


// struct unless you have to make this a class to fit into the system, 

// but then it may be a bit more complicated

struct AnyThing {

    let _value: () -> Flavor

    var value: Flavor { return _value() }

    init<T: Flavor>(thing: Thing<T>) {

        _value = { return thing.value }

    }

}


var dict = [String:AnyThing]()

dict["foo"] = AnyThing(thing: Thing<Vanilla>(value: Vanilla()))

類型擦除器的具體信息可能會有所不同,具體取決于您的基礎(chǔ)類型。


順便說一句:關(guān)于此問題的診斷已經(jīng)相當(dāng)不錯。如果您嘗試addElement在Xcode 9中調(diào)用上述代碼,則會得到以下信息:


Cannot pass immutable value as inout argument: implicit conversion from '[Int]' to '[Any]' requires a temporary

這告訴您的是,Swift愿意將[Int]您要求的位置[Any]作為數(shù)組的特殊情況傳遞給您(盡管這種特殊待遇并未擴展到其他泛型類型)。但是它只能通過制作數(shù)組的臨時(不可變)副本來允許它。(這是另一個很難解釋Swift性能的示例。在其他語言中看起來像“廣播”的情況下,Swift可能會復(fù)制一個副本。或者可能不會復(fù)制。很難確定。)


查看完整回答
反對 回復(fù) 2019-11-04
?
Smart貓小萌

TA貢獻1911條經(jīng)驗 獲得超7個贊

解決此問題的一種方法是向其中添加一個初始化程序,Thing并創(chuàng)建一個Thing<Flavor>保存Vanilla對象的對象。


它看起來像:


class Thing<T> {


    init(thing : T) {

    }


}


protocol Flavor {}


class Vanilla: Flavor {}


var dict = [String:Thing<Flavor>]()


dict["foo"] = Thing<Flavor>(thing: Vanilla())


查看完整回答
反對 回復(fù) 2019-11-04
?
婷婷同學(xué)_

TA貢獻1844條經(jīng)驗 獲得超8個贊

請注意,您的反例inout僅說明了作為inout參數(shù)傳遞的變量必須具有不變性(inout讀和寫該變量都可以)。并不是因為任意泛型都是不變的(實際上,正如您在編輯中強調(diào)的那樣,這Array是一種特殊情況- [Int]確實是的子類型[Any],但是您的示例仍然正確地是非法的)。您也可以看到根本沒有泛型,例如func foo(a: inout Any, b: Any) { a = b }; var i = 1; foo(a: &i, b: "Stuff"),這是非法的。

查看完整回答
反對 回復(fù) 2019-11-04
  • 3 回答
  • 0 關(guān)注
  • 832 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號