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)
上一篇 2021年12月26日 下午4:00
下一篇 2021年12月26日 下午4:00


相关推荐

  • 谷歌疯了?NanoBanana Pro 4K画质APi接入只要0.09?(附使用教程)

    谷歌疯了?NanoBanana Pro 4K画质APi接入只要0.09?(附使用教程)

    2026年3月15日
    4
  • linux查看redis安装目录&查看redis端口占用

    linux查看redis安装目录&查看redis端口占用如果命令 which 和 whereis 都找不到安装目录 可使用以下办法 ps ef grepredis 得到了进程号 xxxx 然后 ls l proc xxxx cwd

    2026年3月20日
    2
  • CCProxy使用指南

    CCProxy使用指南目标是让一个电脑上安装 CCProxy 然后其他电脑也是使用这台电脑上 VPN 下载 amp 安装 http update youngzsoft com ccproxy update ccproxysetup exe 服务端配置进入设置页面记住上面的端口 一般 HTTP 和 HTTPS 用的比较多 都是 808 端口点击上面的高级按钮 选择网络 确保配置正确 git 配置 gitconfigglo proxyhttp vpn kamputer online 808gitco

    2026年3月18日
    2
  • 从0到1打造一个知识库 AI Agent(智能体)

    从0到1打造一个知识库 AI Agent(智能体)

    2026年3月15日
    2
  • linux下ipvsadm命令,ipvsadm命令

    linux下ipvsadm命令,ipvsadm命令ipvsadm 命令用于在 Linux 内核中设置 维护或检查虚拟服务器表 Linux 虚拟服务器可用于基于两个或更多节点的集群构建可伸缩网络服务 群集的主节点将服务请求重定向到将实际执行服务的服务器主机集合 支持的功能包括两种协议 TCP 和 UDP 三种数据包转发方法 NAT 隧道和直接路由 以及八种负载均衡算法 roundrobin 加权循环 最小连接 加权最小连接 基于位置 最小连接 基于

    2026年3月18日
    2
  • C语言 最简分式

    C语言 最简分式Description 我们知道 5 3 1 3 5 称等号后面的式子为最简分式 也就是说 在分式中 分子一定要小于分母 而且分子 分母是互质的 请写一个程序 对于用户输入的一个合法分式 输出其约简之后的结果 Input 输入有多行 每行是 m n 的格式表示的一个分式 其中 m 和 n 都是 int 类型范围内的正整数 输入至 EOF 结束 Output 输出的行数与输入一致 且每行输出与上述输入一一对应 如果约简后 分子部分是 0 则只输出整数部分 如果整数部分是 0 则按照 j k 的格式输出 如果整数部分不

    2026年3月20日
    2

发表回复

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

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