Framework中的struct

正常情況下,struct的用法是這樣的:

struct Person {
    var name: String
    var age: Int
}

let person = Person(name: "Ken", age: 3)
print(person.name)

如果把Person的定義放到一個(gè)叫PeopleFramework中去,然后在調(diào)用的地方加上import語(yǔ)句來(lái)引用

import People

這樣會(huì)報(bào)錯(cuò):

Use of unresolved identifier 'Person'

因?yàn)?code>Framework里的定義要聲明為public才能給外部使用。如下:

public struct Person {
    var name: String
    var age: Int
}

但這樣還是會(huì)報(bào)錯(cuò):

'Person' cannot be constructed because it has no accessible initializers

因?yàn)橐话闱闆r下,struct在沒(méi)有自定義init時(shí),會(huì)自動(dòng)生成一個(gè)全部成員的init,如下:

init(name: String, age: Int) {
    self.name = name
    self.age = age
}

但是一放到Framework中,怎么又提示"no accessible initializers"呢?
請(qǐng)看官方文檔的描述:

"Default Memberwise Initializers for Structure Types The default memberwise initializer for a structure type is considered private if any of the structure’s stored properties are private. Otherwise, the initializer has an access level of internal.

As with the default initializer above, if you want a public structure type to be initializable with a memberwise initializer when used in another module, you must provide a public memberwise initializer yourself as part of the type’s definition."

也就是說(shuō)這個(gè)自動(dòng)生成的init的access level默認(rèn)情況下是internal(如果有任何成員是private,則它也會(huì)降為private)。而像前面提到過(guò)的,標(biāo)記為public的定義才能被Framework外部訪問(wèn)。所以自己寫(xiě)一個(gè)publicinit就好了。

不太理解為什么要這樣設(shè)計(jì),明白的同學(xué)還請(qǐng)指教。

代碼變成這樣:

public struct Person {
    var name: String
    var age: Int
    
    public init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}
let person = Person(name: "Ken", age: 11)
print(person.name)

但這樣依然會(huì)報(bào)錯(cuò):

Value of type 'Person' has no member 'name'

這是因?yàn)樯厦娴?code>Person雖然定義成了public,但成員還是internal的,要訪問(wèn)必須加上public。這個(gè)設(shè)計(jì)雖然稍顯啰嗦,但還是比較嚴(yán)謹(jǐn)?shù)摹?/p>

最終代碼:

public struct Person {
    public var name: String
    public var age: Int
    
    public init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}
let person = Person(name: "Ken", age: 11)
print(person.name)

參考:
How can I make public by default the member-wise initialiser for structs in Swift?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容