简体   繁体   English

协议一致性的Swift访问控制

[英]Swift access control on protocol conformance

I have a private protocol defined in a file as below 我有一个在文件中定义的私有协议,如下所示

private protocol testProtocol {
 func testFunc1()
 func testFunc2()
}

A public class conforms to the above protocol as follows 公共类符合上述协议如下

 public class testClass : testProtocol {
 func testFunc1() {}
 func testFunc2() {}
}

As per apples documentation , the members of a public class get internal access control by default unless it is explicitly set to a different access control modifier. 根据apples文档,默认情况下,公共类的成员获得内部访问控制,除非它明确设置为不同的访问控制修饰符。

The documentation also says that a type's conformance to a protocol with a lower access control will make the type's implementation of the protocol access control the same as that of the protocol. 该文档还说,类型与具有较低访问控制的协议的一致性将使该类型的协议访问控制的实现与协议的实现相同。 In this scenario since the type's access control is public and the protocols access control is private , the methods testfunc1 and testfunc2 should get an access control of private. 在这种情况下,由于类型的访问控制是公共的,并且协议访问控制是私有的,因此方法testfunc1和testfunc2应该获得私有的访问控制。

When the class is instantiated in a different source file and the methods are accessed as below , the compiler does not show an error which is not expected as the methods should be private as per the guidelines 当在不同的源文件中实例化类并且如下所示访问方法时,编译器不会显示不期望的错误,因为根据指南,方法应该是私有的

var test: testClass = testClass()
test.testFunc1()

Is this expected behavior ? 这是预期的行为吗? Am i missing something? 我错过了什么吗?

Apple Documentation says: Apple文档说:

When you write or extend a type to conform to a protocol, you must ensure that the type's implementation of each protocol requirement has at least the same access level as the type's conformance to that protocol. 在编写或扩展类型以符合协议时,必须确保每个协议要求的类型实现至少具有与该协议类型一致的访问级别。

According to this I assume that implementing methods testFunc1 and testFunc2 with another access control modifier inside testClass just overrides that from protocol. 根据这一点,我假设在testClass中使用另一个访问控制修饰符实现方法testFunc1和testFunc2只是覆盖了来自协议的方法。 If you use default protocol implementation of this methods like the following compiler will return error: 如果使用此方法的默认协议实现,则以下编译器将返回错误:

extension testProtocol {
    func testFunc1() {}
    func testFunc2() {}
}

As far as Swift is Protocol Oriented Language with replacing inheritance with protocols it's probably reasonable if you want to change protocol defined access level of function inside your custom class. 至于Swift是面向协议的语言,用协议替换继承,如果你想在自定义类中更改协议定义的函数访问级别,这可能是合理的。

According to Apple's documentation: 根据Apple的文档:

When you write or extend a type to conform to a protocol, you must ensure that > the type's implementation of each protocol requirement has at least the same > access level as the type's conformance to that protocol. 在编写或扩展类型以符合协议时,必须确保>每种协议要求的类型实现至少具有与该协议类型一致的访问级别。

Please be aware of the "at least" in the doc, it means that the as long as the access level of the type's implementation of the protocol requirements is higher or equal to the access level of the protocol, it will be ok. 请注意文档中的“至少” ,这意味着只要协议要求的类型实现的访问级别高于或等于协议的访问级别,就可以了。 In your case, testFunc1 and testFunc2 from testClass have the default access level of internal, it is higher than access level of private. 在您的情况下,testClass中的testFunc1和testFunc2具有内部的默认访问级别,它高于私有的访问级别。 So actually the two methods in testClass get the access level of internal, and compiler won't treat it as en error. 所以实际上testClass中的两个方法获得了内部的访问级别,编译器不会将其视为错误。

We can change your code a little bit as follows: 我们可以更改您的代码,如下所示:

    fileprivate protocol TestProtocol {
        func testFunc1()
        func testFunc2()
    }

    public class TestClass : TestProtocol {
        public func testFunc1() {}
        public func testFunc2() {}
   }

This piece of code will also compile without an error. 这段代码也将编译而没有错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM