正常情況下,struct的用法是這樣的:
struct Person {
var name: String
var age: Int
}
let person = Person(name: "Ken", age: 3)
print(person.name)
如果把Person的定義放到一個叫People的Framework中去,然后在調(diào)用的地方加上import語句來引用
import People
這樣會報錯:
Use of unresolved identifier 'Person'
因為Framework里的定義要聲明為public才能給外部使用。如下:
public struct Person {
var name: String
var age: Int
}
但這樣還是會報錯:
'Person' cannot be constructed because it has no accessible initializers
因為一般情況下,struct在沒有自定義init時,會自動生成一個全部成員的init,如下:
init(name: String, age: Int) {
self.name = name
self.age = age
}
但是一放到Framework中,怎么又提示"no accessible initializers"呢?
請看官方文檔的描述:
"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."
也就是說這個自動生成的init的access level默認(rèn)情況下是internal(如果有任何成員是private,則它也會降為private)。而像前面提到過的,標(biāo)記為public的定義才能被Framework外部訪問。所以自己寫一個public的init就好了。
不太理解為什么要這樣設(shè)計,明白的同學(xué)還請指教。
代碼變成這樣:
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)
但這樣依然會報錯:
Value of type 'Person' has no member 'name'
這是因為上面的Person雖然定義成了public,但成員還是internal的,要訪問必須加上public。這個設(shè)計雖然稍顯啰嗦,但還是比較嚴(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?