为了账号安全,请及时绑定邮箱和手机立即绑定

Swift有访问修饰符吗?

Swift有访问修饰符吗?

烙印99 2019-09-19 10:33:18
在Objective-C实例中,数据可以是public,protected或private。例如:@interface Foo : NSObject{  @public    int x;  @protected:    int y;  @private:    int z;  }-(int) apple;-(int) pear;-(int) banana;@end我没有在Swift参考中找到任何访问修饰符。是否可以限制Swift中数据的可见性?
查看完整描述

3 回答

?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

Swift 4 / Swift 5

正如Swift文档中提到的- 访问控制,Swift有5个访问控制:


open和 public:可以从模块的实体和导入定义模块的任何模块实体访问。


internal:只能从其模块的实体访问。这是默认的访问级别。


fileprivate和 private:只能在您定义它们的有限范围内限制访问。




开放和公共有什么区别?

open与以前版本的Swift中的public相同,它们允许来自其他模块的类使用和继承它们,即:它们可以从其他模块中继承。此外,它们允许来自其他模块的成员使用和覆盖它们。他们的模块也采用相同的逻辑。


public允许来自其他模块的类使用它们,但不能继承它们,即:它们不能从其他模块中继承。此外,它们允许来自其他模块的成员使用它们,但不要覆盖它们。对于他们的模块,它们具有相同的开放逻辑(它们允许类使用和继承它们;它们允许成员使用和覆盖它们)。




fileprivate和private有什么区别?

fileprivate可以从他们的整个文件中访问。


private只能从它们的单个声明和同一文件中的声明的扩展名进行访问; 例如:


// Declaring "A" class that has the two types of "private" and "fileprivate":

class A {

    private var aPrivate: String?

    fileprivate var aFileprivate: String?


    func accessMySelf() {

        // this works fine

        self.aPrivate = ""

        self.aFileprivate = ""

    }

}


// Declaring "B" for checking the abiltiy of accessing "A" class:

class B {

    func accessA() {

        // create an instance of "A" class

        let aObject = A()


        // Error! this is NOT accessable...

        aObject.aPrivate = "I CANNOT set a value for it!"


        // this works fine

        aObject.aFileprivate = "I CAN set a value for it!"

    }

}



Swift 3和Swift 4 Access Control有什么区别?

正如SE-0169提案中所提到的,Swift 4中唯一的改进是私有访问控制范围已扩展为可以从同一文件中的声明扩展访问; 例如:


struct MyStruct {

    private let myMessage = "Hello World"

}


extension MyStruct {

    func printMyMessage() {

        print(myMessage)

        // In Swift 3, you will get a compile time error:

        // error: 'myMessage' is inaccessible due to 'private' protection level


        // In Swift 4 it should works fine!

    }

}

所以,没有必要宣布myMessage为fileprivate是在整个文件进行访问。


查看完整回答
反对 回复 2019-09-19
?
万千封印

TA贡献1891条经验 获得超3个赞

当谈到在Swift或ObjC(或ruby或java或......)中制作“私有方法”时,这些方法并不是真正私有的。它们周围没有实际的访问控制。任何提供甚至一点内省的语言都可以让开发人员从课堂外获得这些价值,如果他们真的想要的话。


所以我们在这里真正谈到的是一种定义面向公众的界面的方法,该界面仅提供我们想要的功能,并“隐藏”我们认为“私有”的其余部分。


用于声明接口的Swift机制是protocol,它可以用于此目的。


protocol MyClass {

  var publicProperty:Int {get set}

  func publicMethod(foo:String)->String

}


class MyClassImplementation : MyClass {

  var publicProperty:Int = 5

  var privateProperty:Int = 8


  func publicMethod(foo:String)->String{

    return privateMethod(foo)

  }


  func privateMethod(foo:String)->String{

    return "Hello \(foo)"

  }

}

请记住,协议是一流的类型,可以在任何类型的地方使用。而且,当以这种方式使用时,它们只暴露自己的接口,而不是实现类型的接口。


因此,只要您使用MyClass而不是MyClassImplementation在您的参数类型等,它应该只是工作:


func breakingAndEntering(foo:MyClass)->String{

  return foo.privateMethod()

  //ERROR: 'MyClass' does not have a member named 'privateMethod'

}

有一些直接分配的情况,你必须明确的类型,而不是依靠Swift推断它,但这似乎不是一个交易破坏者:


var myClass:MyClass = MyClassImplementation()

使用协议这种方式是语义的,相当简洁,我的眼睛看起来很像我们在ObjC中用于此目的的类扩展。


查看完整回答
反对 回复 2019-09-19
  • 3 回答
  • 0 关注
  • 627 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信