Swift 值类型和引用类型

Swift中的类型分为两类:一,值类型(valuetypes),每个值类型的实例都拥有各自唯一的数据,通常它们是结构体,枚举或元组;二,引用类型(referencetypes),引用类型的实例共享

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

Swift中的类型分为两类:一,值类型(value types),每个值类型的实例都拥有各自唯一的数据,通常它们是结构体,枚举或元组;二,引用类型(reference types),引用类型的实例共享它们的数据,通常是一个类。在这篇文章中我们将会探索值类型和引用类型的价值,以及如何在它们二者间抉择。

 

有什么区别?

值类型最基本的特征就是复制在赋值、初始化和传递参数过程中的数据,并为这个数据创建一个独立的实例:
 
// 值类型例子
struct S { var data: Int = -1 }
var a = S()
var b = a						// 把a复制给b
a.data = 42						// a被改变了, b却没有
println("\(a.data), \(b.data)")	// prints "42, -1"
/* 何问起 hovertree.com */

  

复制一个引用类型的时候,其实是隐式地创建了一个共享的实例。在复制后,两个实例指向了同一块数据,所以当修改其中一个实例数据的时候,另一个实例的数据也被修改了,比如:

 

// 引用类型的例子
class C { var data: Int = -1 }
var x = C()
var y = x						// x被复制给了y
x.data = 42						// x指向的数据被修改了 (同时y也被修改了)
println("\(x.data), \(y.data)")	// prints "42, 42"
/* 何问起 hovertree.com */

  

可变性在安全中的作用

选择值类型而不是引用类型的一个主要原因是能让你的代码变得更加简单。你在任何情况下用一个值类型,都能够假设你的其他代码不会使它改变,这通常在多线程环境中很有用,如果一个线程中使用的数据被另一个线程给意外的修改了,这通常会产生非常严重的Bug,且相当难以调试。
由于只有当你需要修改数据时两者的区别才会得到体现,所以当你的实例不会对数据进行修改的时候,值类型和引用类型看起来是完全相同的。
你也许会想,写一个完全不可变的类,这或许是有价值的,使用Cocoa的NSObject能简化这个过程,并且能很好地保持原有的语义。现在,你能通过使用不可变的存储属性,以及避免暴露修改数据的接口,从而在Swift里实现一个不可变的类。事实上,大多数的Cocoa类,比如NSURL等,都被设计为不可变的类,然而,Swift当前并没有提供任何语言机制去强制申明一个类不可改变(比如子类化就能修改一个类的实现),只有结构体和枚举才是强制不可变的。
 

如何选择?

所以如果你想要创建一个新的类型,你怎么选择?当你写Cocoa程序的时候,大多数APIs都需要从NSObject继承,你就已经是一个类了(引用类型),针对其他情况,这里有些指导规则:
使用值类型,当…:
  • 通过使用==去比较实例的数据
  • 你想得到一个实例的独立副本
  • 数据在多线程环境下被修改
 
使用引用类型(比如使用一个类),当…:
  • 通过使用===去判断两个实例是否恒等
  • 你想要创建一个共享的,可变的对象
在Swift里,Array、String和Dictionary都是值类型,他们的行为和C语言中的int类似,每个实例都有自己的数据,你不需要额外做任何事情,比如做一个显式的copy,防止其他代码在你不知情的情况下修改等,更重要的是,你能安全地在线程间传递它,而不需要使用同步技术。在提高安全性的精神下,这个模型将帮助你在Swift中写出更多可预知的代码。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120389.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 什么是Lambda架构?

    什么是Lambda架构?写在前面本文隶属于专栏《100个问题搞定大数据理论体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!本专栏目录结构和文献引用请见100个问题搞定大数据理论体系解答1.Lambda架构定义了一套面向大数据应用的模式和准则。更重要的是,它允许同时查询历史数据和实时新增的数据,并且获得期望的分析视图。2.处理历史数据(批处理)和实时数据。3.技术无关和通用性。Lambda架构是一种通用的模式,完全不依赖于任何技术,而且任何技术只要能满足需求,都可以在Lamb

    2022年6月25日
    25
  • linux系统中如何卸载删除软件_卸载预装软件app

    linux系统中如何卸载删除软件_卸载预装软件appLinux下如何卸载软件比如我在Linux下安装了Mysql,但是现在我要卸载重装,提示卸载失败,有其它的服务或软件如php-mysql-5.1.6-3;mysql-server-5.0.22-2.1依赖于Mysql。我可以加–nopeds来卸载Mysql,但是依赖于Mysql的软件或服务是不是也要卸载?我把Mysql卸载了,现在安装了RPM包的mysql-server和Mysql-client…

    2022年9月9日
    0
  • TaskScheduler_taskset -p

    TaskScheduler_taskset -p目录1、DAGScheduler与TaskScheduler2、TaskScheduler与SchedulerBackend3、任务调度过程总结1、DAGScheduler与TaskSchedulerDAGScheduler面向我们整个Job划分出了Stage,划分了Stage是从后往前划分的,执行的时候是从前往后,每个Stage内部有一系列任务,Stage里面的任务是并…

    2022年10月11日
    0
  • postman 中post方式提交数据

    postman 中post方式提交数据

    2021年9月18日
    29
  • 基于faster-rcnn的目标物体检测_传统的目标检测算法

    基于faster-rcnn的目标物体检测_传统的目标检测算法继RCNN,fastRCNN之后,目标检测界的领军人物RossGirshick在2015年提出fasterRCNN。目标检测速度达到15fps。

    2022年10月13日
    0
  • AdventureWorks2008R2安装过程可能会遇到的一些问题及解决方案

    AdventureWorks2008R2安装过程可能会遇到的一些问题及解决方案AdventureWorks2008R2范例数据库对于学习SQLServer2008R2是一个非常好的学习案例库,里面包含了一些详尽的数据库案例(官网下载)。但是如果直接安装的话,可能会遇到一些问题,下面介绍安装的一些必要前提:1.安装的数据库账户应具有系统权限。2.你所安装的数据库至少是”SQLServerExpresswithAdvancedServices“版本(我所安…

    2022年9月11日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号