【问题标题】:Implementing a public protocol with internal class in swift快速实现具有内部类的公共协议
【发布时间】:2015-10-30 11:43:21
【问题描述】:

所以我正在编写一个 Swift 框架,我想只通过 protocol 公开一些对象。

例如:

public protocol Thing : class {
    var x : Int { get }
}

我想隐藏我的实现细节,所以我创建了一个internal 类:

internal class ThingImpl : Thing {
    public private(set) var x : Int = 0
}

并通过工厂方法出售新的Things

public func newThing() -> Thing {
    return ThingImpl()
}

我无法理解的是为什么编译器会警告我不要在 ThingImpl 内创建 var x public 并鼓励我将其声明为内部。

尽管有警告,但一切正常,如果我留意警告并更改为internal private(set) var x : Int = 0,警告就会消失,一切仍然正常。

在我看来,使 var 公开是正确的做法,因为它在它正在实施的公共协议中是公开的。 我在这里错过了什么吗?谢谢。

【问题讨论】:

    标签: swift swift2


    【解决方案1】:

    ThingImpl 是一个内部类。因此它将覆盖公共x 变量的可访问性,从而有效地使该变量成为内部变量。所以,将此变量的可访问性设置为public 是多余的。

    【讨论】:

    • 但是由于 Thing 协议它是公开的,对吧?
    • 如果您通过Thing 协议访问它,它是公开的。但是您不能从其他模块通过ThingImpl 访问x。我的意思是,两个案例不相关
    • 是的,我想是他们没有关系,我很难接受。我的意思是,ThingImpl 被声明为向 Thing(它是公共的)确认,因此它必须有一个公共 var x : Int { get }。啊! :)
    【解决方案2】:

    牢记this

    • private:仅对其源文件可用
    • 内部:对其整个模块可用
    • 公开:所有人都可以使用

    你的实现类:

    internal class ThingImpl : Thing {
        <#access#> var x : Int = 0
    }
    

    访问控制可能性:

    • private:不可能,x 需要有读取权限才能符合 Thing(协议中的属性是设计为公开的)
    • public:在内部类中没有多大意义,但它可以编译(带有警告)
    • private(set): 它将只允许在同一个源文件中修改 x
    • internal: 是默认的,如果你不设置任何访问控制,它会允许在同一个模块(框架,目标等)中修改 x
    • public private(set):同时创建变量publicprivate 没有多大意义,不是吗?如果它在 internal 类中,则更少。

    恕我直言,有两个合理的选择:

    • 不要包含任何访问控制,让 x 在模块中可写
    • 使用private(set) 限制对其文件的写入权限

    【讨论】:

    • 是的,问题是采用公共协议使变量公开可读。
    • public private(set) 是有道理的,因为我希望公共接口(协议)包含一个只读变量,但能够在我的私有/内部实现中对其进行修改。
    • 事物中的x 是只读的(您只在其声明中包含get)。使用internal(或只是空白),您可以做到这一点:x 是可读的,因为 Thing 以这种方式声明它,并且它是内部可写的(在同一个模块中)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-23
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多