美文网首页
Framework中的struct

Framework中的struct

作者: 张宇航_Ken | 来源:发表于2016-08-12 21:42 被阅读74次

    正常情况下,struct的用法是这样的:

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

    如果把Person的定义放到一个叫PeopleFramework中去,然后在调用的地方加上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默认情况下是internal(如果有任何成员是private,则它也会降为private)。而像前面提到过的,标记为public的定义才能被Framework外部访问。所以自己写一个publicinit就好了。

    不太理解为什么要这样设计,明白的同学还请指教。

    代码变成这样:

    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。这个设计虽然稍显啰嗦,但还是比较严谨的。

    最终代码:

    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?

    相关文章

      网友评论

          本文标题:Framework中的struct

          本文链接:https://www.haomeiwen.com/subject/qtwssttx.html