正常情況下,struct
的用法是這樣的:
struct Person {
var name: String
var age: Int
}
let person = Person(name: "Ken", age: 3)
print(person.name)
如果把Person
的定義放到一個(gè)叫People
的Framework
中去,然后在調(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è)public
的init
就好了。
不太理解為什么要這樣設(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?