Swift Access Control访问控制与断言详细介绍

目录
  • 访问控制(Access Control)
  • 访问级别的使用准则
  • 元组类型
  • 泛型类型
  • 成员、嵌套类型
  • getter与setter
  • 初始化器
  • 枚举类型的case
  • 协议
  • 扩展
  • 将方法赋值给var\let
  • 一些补充知识
    • CustomStringConvertible
    • Self
    • assert (断言)
    • fatalError

访问控制(Access Control)

1、在访问权限控制这块,Swift提供了5个不同的访问级别(以下是从高到低排序,实体指被访问级别修饰的内容)

  • open:允许在定义实体的模块、其他模块中访问,允许其他莫模块进行继承、重写(open只能用在类、类成员上)
  • public:允许在定义实体的模块、其他模块中访问,不允许其他模块进行继承、重写
  • internal:只允许在定义实体的模块中访问,不允许在其他模块中访问
  • fileprivate:只允许在定义实体的源文件中访问
  • private:只允许在定义实体的封闭声明中访问

2、绝大部分实体默认都是internal级别

访问级别的使用准则

1、一个实体不可以被更低访问级别的实体定义,比如

  • 变量\常量类型 >= 变量\常量
  • 参数类型、返回值类型 >= 函数
  • 父类 >= 子类
  • ……

元组类型

1、元组类型的访问界别是所有成员类型最低的那个

internal struct Dog {}
fileprivate class Person {}

//(Dog, Person)的访问级别是fileprivate
fileprivate var data1: (Dog, Person)
private var data2: (Dog, Person)

泛型类型

1、泛型类型的访问级别是 类型的访问级别 以及 所有泛型类型参数的访问级别 中最低的那个

成员、嵌套类型

1、类型的访问级别会影响成员(属性、方法、初始化器、下标)嵌套类型的默认访问级别

  • 一般情况下,类型为private或fileprivate,那么成员\嵌套类型默认也是private或fileprivate
  • 一般情况下,类型为internal或public,那么成员\嵌套类型默认是internal

2、直接在全局作用域下定义的private等价于fileprivate

private struct Dog {
    var age: Int = 0
    func run() {}
}
fileprivate struct Person {
    var dog: Dog = Dog()
    mutating func walk() {
        dog.run()
        dog.age = 1
    }
}

3、子类重写的成员访问级别必须 >= 父类的成员访问级别

getter与setter

1、getter、setter默认自动接收他们所属环境的访问级别

2、可以给setter单独设置一个比getter更低的访问级别,用以限制写的权限

fileprivate(set) public var num = 10
class Person {
    private(set) var age = 0
    fileprivate(set) public var weight: Int {
        set {}
        get { 10 }
    }
    internal(set) public subscript(index: Int) -> Int {
        set {}
        get { index }
    }
}

初始化器

1、如果一个public类想在另一个模块调用编译生成的默认无参初始化器,必须显式提供public的无参初始化器

因为public类的默认初始化器时internal级别的

2、required初始化器必须跟他所属类拥有相同的访问级别

3、如果结构体有private\fileprivate的存储实例属性,那么它的成员初始化器也是private\fileprivate

否则默认就是internal

枚举类型的case

1、不能给enum的每个case单独设置访问级别

2、每个case自动接收enum的访问级别

public enum定义的case也是public

协议

1、协议中定义的要求(方法)自动接收协议的访问级别,不能单独设置访问级别

public协议定义的要求(方法)也是public

2、协议实现的访问级别必须 >= 类型的访问级别,或者 >= 协议的访问级别

扩展

1、如果有显式设置扩展的访问级别,扩展添加的成员自动接收扩展的访问级别

2、如果没有显式设置扩展的访问级别,扩展添加的成员的默认访问级别,跟直接在类型中定义的成员一样

3、可以单独给扩展添加的成员设置访问级别

4、不能给用于遵守协议的扩展显式设置扩展的访问级别

5、在同一文件中的扩展,可以写成类似多个部分的类型声明

  • 在原本的声明中声明一个私有成员,可以在同一文件的扩展中访问他
  • 在扩展中声明一个私有成员,可以在同一文件的其他扩展中、原本生明中访问他

将方法赋值给var\let

1、方法也可以像函数那样,赋值给一个let或者var

struct Person {
    var age: Int
    func run(_ v: Int) {
        print("func run", age, v)
    }
}
var fn: (Person) -> (Int) -> () = Person.run(_:)
fn(Person(age: 10))(20)

一些补充知识

CustomStringConvertible

1、遵守CustomStringConvertible、CustomDebugStringConvertible协议,都可以自定义实例的打印字符串

class Person: CustomStringConvertible, CustomDebugStringConvertible {
    var age = 0
    var description: String {
        "person_\(age)"
    }
    var debugDescription: String {
        "debug_person_\(age)"
    }
}

2、print调用的是CustomStringConvertible协议的description

3、debugPrint、po调用的是CustomDebugStringConvertible协议的debugDescription

Self

1、Self一般用作返回值类型,限定返回值跟方法调用者必须是同一类型(也可以作为参数类型)

2、Self代表当前类型

class Person {
    var age = 1
    static var count = 2
    func run() {
        print(self.age) // 1
        print(Self.count) // 2
    }
}

assert (断言)

1、很多编程语言都有断言机制:不符合指定条件就抛出运行时错误,常用语调试(Debug)阶段的条件判断

2、默认情况下,Swift的断言只会在debug模式下生效,release模式下会忽略

func divide(_ v1: Int, _ v2: Int) -> Int {
    assert(v2 != 0, "除数不能为0")
    return v1 / v2
}

fatalError

1、如果遇到严重问题,希望结束程序运行时,可以直接使用fatalError函数抛出错误(这是无法通过do-catch捕捉的错误)

2、使用了fatalError函数,就不需要再写return

func test(_ num: Int) -> Int {
    if num >= 0 {
        return 1
    }
    fatalError("num不能小于0")
}

3、在某些不得不实现,但不希望别人调用的方法,可以考虑内部使用fatalError函数

class Person {
    required init() {}
}
class Student: Person {
    required init() {
        fatalError("don't call Student init()")
    }
    init(score: Int) {}
}
var stu1 = Student(score: 98)
var stu2 = Student()

到此这篇关于Swift Access Control访问控制与断言详细介绍的文章就介绍到这了,更多相关Swift Access Control内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Swift中的Access Control权限控制介绍

    如果您之前没有接触过权限控制,先来听一个小故事: 小明是五道口工业学院的一个大一新生,最近他有点烦恼,因为同屋经常用他的热水壶,好像那是自己家的一样,可是碍于同学情面,又不好意思说.直到有一天,他和学姐小K吐槽. 学姐听了之后,说:大学集体生活里面,大部分东西都是默认室友可以共用的.如果你不想别人拿,我可以帮你做封印,只要打上private标记,它们就看不到你的东西,更加用不了你的东西了. 小明说哇靠学姐你还会妖法...... Swift语言从Xcode 6 beta 5版本起,加入了对权限控制

  • Swift学习教程之访问控制详解

    前言 本文主要给大家介绍了关于Swift访问控制的相关内容,访问控制对访问你的其他代码源文件和模块部分进行了约束.这个特性允许你隐藏你的代码实现,并且指定通过其可以访问和使用该代码的优选接口. class,structure 和 enumeration 都可以指定访问级别,当然,property,method,initializer 和 属于这里类型的 subscript.protocol 可以限制到某个上下文,全局变量,变量和函数也可以. 另外,Swift 也提供默认的使用级别给典型的使用场景

  • Swift语言中的一些访问控制设置详解

    限制访问代码块,模块和抽象通过访问控制来完成.类,结构和枚举可以根据自己的属性,方法,初始化函数和下标来通过访问控制机制进行访问.常量,变量和函数的协议限制,并允许通过访问控制来访问全局和局部变量.应用于属性,类型及函数的访问控制可以被称为"实体". 访问控制模型是基于模块和源文件的. 模块定义为代码分配一个单独的单元,并且可以使用import 关键字导入.源文件被定义为一个单一的源代码文件,模块可访问多种类型和函数. 三种不同的访问级别是由 Swift 语言提供.它们分别是 Publ

  • 深入理解Swift中的访问控制关键字

    前言 在Swift3.0以前有三种访问控制关键字,分别是private.internal和public.而在swift3以后,又在原来的基础上增加了两种访问控制关键字:fileprivate和open.他们可以看作是private和public的进一步细分.下面是各个修饰符的区别以及访问权限排序. 各个修饰符的区别 private swift3.0 private访问级别所修饰的属性或者方法只能在当前类里访问. class A { private func test() { print("thi

  • Swift中的访问控制和protected

    原文再续,书折第一回. 很多其他编程语言都有一种"protected"设定,可以限制某些类方法只能被它的子类所使用. Swift支持了访问控制后,大家给我们的反馈都很不错.而有的开发者问我们:"为什么Swift没有类似protected的选项?" 当我们在设计Swift访问控制的不同等级时,我们认为有两种主要场景: ●在一个APP里:隐藏某个类的私密细节. ●在一个开源框架里:不让导入这个框架的APP,随便接触框架的内部实现细节. 上面的两种常见情况,对应着priv

  • Swift Access Control访问控制与断言详细介绍

    目录 访问控制(Access Control) 访问级别的使用准则 元组类型 泛型类型 成员.嵌套类型 getter与setter 初始化器 枚举类型的case 协议 扩展 将方法赋值给var\let 一些补充知识 CustomStringConvertible Self assert (断言) fatalError 访问控制(Access Control) 1.在访问权限控制这块,Swift提供了5个不同的访问级别(以下是从高到低排序,实体指被访问级别修饰的内容) open:允许在定义实体的模

  • Java超详细介绍封装与访问控制修符

    概念:我们在写入一个类的时候,为了保护里边的属性不被随意的调用这是我们可以使用特殊的修饰符进行相应的保护,而这样的话我们似乎只能在该类中调用使用了,出现某些特殊情况时就会无法发调用,虽然挺高了安全性但也降低了灵活性,这个时候我们的包装类就出现了,我们通过对某个方法的进行特殊方法的包装来对其进行相应的调用与赋值.就相当于银行为了保护财产会选择将金钱放进保险柜中来确保其的安全,但是当我们要取钱时,银行就要拿钥匙打开保险柜.修饰符相当于银行的保险柜,封装相当于保险柜的钥匙. 访问修饰符如下: 1) p

  • Swift Extension扩展得使用详细介绍

    目录 扩展(Extension) 协议与初始化器 协议 泛型 扩展(Extension) 1.Swift中的扩展,有点类似于OC中的分类(Category) 2.扩展可以为枚举.结构体.类.协议添加新功能 可以添加方法.计算属性.下标.(便捷)初始化器.嵌套类型.协议等等 3.扩展不能办到的事情 不能覆盖原有的功能 不能添加存储属性,不能向已有的属性添加属性观察器 不能添加父类 不能添加指定初始化器,不能添加反初始化器 .... extension Double { var km: Double

  • oracle 虚拟专用数据库详细介绍

    所谓虚拟专用数据库(VPD)指的是,通过在数据库里进行配置,从而让不同的用户只能查看某个表里的部分数据.VPD分为以下两个级别. 行级别:在该级别下,可以控制某些用户只能查看到某些数据行.比如,对于销售数据表sales 来说,每个销售人员只能检索出他自己的销售数据,不能查询其他销售人员的销售数据. 列级别:在该级别下,可以控制某些用户不能检索某个表的某个列的值.比如用户HR 下的 employees 表中,含有工资(salary)列,由于该列比较敏感,因此不让其他用户查询该列的值. 其他用户检索

  • nginx从编译安装到配置文件说明中文详细介绍

    本文详细介绍了Nginx从编译安装到配置文件说明,每一步都给出了详细介绍,可以作为安装Nginx的指导手册了 好了,费话不多说直接进入主题 1. 安装nginx 1.1 选择稳定版Nginx 我们编译安装nginx来定制自己的模块,机器CentOS 6.2 x86_64.首先安装缺少的依赖包: # yum -y install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel 这些软件包如

  • 正则表达式详细介绍(下)

    本文是前一片文章<正则表达式详细介绍(上)>的续篇,在本文中讲述了正则表达式中的组与向后引用,先前向后查看,条件测试,单词边界,选择符等表达式及例子,并分析了正则引擎在执行匹配时的内部机理. 9. 单词边界 元字符<<\b>>也是一种对位置进行匹配的"锚".这种匹配是0长度匹配. 有4种位置被认为是"单词边界": 1) 在字符串的第一个字符前的位置(如果字符串的第一个字符是一个"单词字符") 2) 在字符串的最

  • Openstack 使用migrate进行数据库升级实现方案详细介绍

    Openstack 使用migrate进行数据库升级实现方案详细介绍 OpenStack中随着版本的切换,新版本加入一些数据库表或者增加字段等是必然的事情,如何比较容易的进行这些数据库升级的适配和管理,这里就要用到oslo_db中的migrate了,这里以为M版本的heat为例,讲解一下migrate管理db的原理. 我们使用migrate需要用到的主要包含以下两部分:1.versions里面的为版本号+数据库适配脚本:2.migrate.cfg为migrate需要用到的配置文件,两部分的命名是

  • iOS 配置.gitignore文件详细介绍

    iOS 配置.gitignore文件详细介绍 为什么要配置.gitigore 在我们使用git的过程当中,不是任何文件都需要commit到本地或者远程仓库的,比如一些三方库文件. 那么作为一个git新手,很多人不知道如何配置.gitignore文件,本文只是提供一个便捷的例子.你可以直接使用本文提供的代码编辑到你的.gitigore文件中. 简便配置 直接复制下面的内容到你的.gitignore文件即可.注意,这个配置是给iOS开发者使用的. # Xcode .DS_Store */build/

  • nginx参数的详细介绍

    nginx参数的详细介绍 最近公司的项目中涉及到旧老项目迁移,需要在nginx上做些配置,所以简单学习了下,好记性不如烂笔头,也许可以帮助到大家, #开启进程数 <=CPU数 worker_processes 1; #错误日志保存位置 #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #进程号保存文件 #pid logs/nginx.pid; #等待事件 eve

随机推荐