深入理解Swift中的变量与常量
发布时间 - 2026-01-10 22:29:19 点击率:次前言

最近在学习Swift这门新语言,对于熟练掌握OC编程的iOS开发者来说其实很容易上手,但Swift的确在语法和编程习惯上改变了很多,对于从未了解OC语言而从Swift开始学习iOS开发的新手来说可能上手有一定难度,下面我将这段时间的学习成果结合在网上搜索的知识做一个简单的汇总,希望可以帮助到正在学习Swift的小伙伴们。
变量和常量的定义
Swift开发文档中是这样定义变量和常量的:常量和变量把名字和一个特定类型的值关联起来。常量的值一旦设置好便不能再被更改,然而变量可以在将来被设置为不同的值(见名知意,很简单了啦)
如何声明变量常量
常量和变量必须在使用前被声明,使用关键字 let 来声明常量,使用关键字 var 来声明变量。举个简单的例子:
class Person: NSObject {
let life = 1
var age = 0
}
这里我们有一个Person类继承NSObject,显然人的生命只有一条应该设置为不可以改变的常量,但是人的年龄是随着时间变化的应该声明为变量,同理,当你在开发过程中有类似需求时应该这样来选择何时使用变量、何时使用常量。
当然我们可以选择一行代码以逗号分隔的形式申明多个简单的变量或常量如下所示:
var a = 0, b = 1.0, c = "CoderYQ"
这里需要讲解一下关于Swift中的类型安全和类型推断。Swift 是一门类型安全的语言,即你必须时刻清楚此时代码需要处理的值的类型,编译器会进行类型检查,任何不匹配的类型都会被标记为错误当然更不能参与运算。当你操作不同类型的值时,类型检查能帮助你避免错误。当然并不是所有的变量和常量都需要明确指出一个确定的类型,如果你没有为申明的变量或常量指定类型,Swift 会使用类型推断的功能推断出合适的类型,通过检查你给变量赋的值,类型推断能够在编译阶段自动的推断出值的类型,这就是Swift中类型推断。就像上面的连续申明变量a、b、c的代码中我们并没有明确指出a、b、c的类型,编译器则是通过你给a、b、c赋的值来推断a、b、c的类型分别为:Int类型、Double类型、String类型。
但是在某些必要时刻我们是需要给申明的变量或常量提供类型标注的,以此来明确他们能够存储的值。添加类型标注的方法是在变量或常量的名字后边加一个冒号,再跟一个空格,最后加上要使用的类型名称(这里和OC中不太一样,需要大家适应一下),如下所示的代码效果其实和上面的是一样的:
var a: Int = 0 var b: Double = 1.0 var c: String = "CoderYQ"
如果变量的类型都一样,我们还可以这样申明:
var a, b, c : Double
变量和常量的命名
常量和变量的名字几乎可以使用任何字符,甚至包括 Unicode 字符:
let π = 3.14159 let 你好 = "你好世界" let 🐶🐮 = "dog cow"
但是要注意一点:常量和变量的名字不能包含空白字符、数学符号、箭头、保留的(或者无效的)Unicode 码位、连线和制表符。也不能以数字开头,尽管数字几乎可以使用在名字其他的任何地方。一旦你声明了一个确定类型的常量或者变量,就不能使用相同的名字再次进行声明,也不能让它改存其他类型的值。常量和变量之间也不能互换,如果你需要使用 Swift 保留的关键字来给常量或变量命名,可以使用反引号( ` )包围它来作为名称。总之,除非别无选择,避免使用关键字作为名字除非你确实别无选择(引自文档翻译,没什么好说的...)。
总结一句:Swift中变量和常量的命名相较于OC中更加灵活多变,但是仍然有上面的规定需要注意,而且他们的命名尽量做到见名知意,以便于开发人员之间的协同合作。这里我给大家列出了Swift中主要的关键字,希望大家在命名的时候尽量规避他们。
用作声明的关键字:
class、deinit、enum、extension、func、import、init、let、protocol、static、struct、subscript、typealias、var
用作语句的关键字:
break、case、continue、default、do、else、fallthrough、if、in、for、return、switch、where、while
用作表达和类型的关键字:
as、dynamicType、is、new、super、self、Self、Type、__COLUMN__、__FILE__、__FUNCTION__、__LINE__
特定上下文中被保留的关键字:
associativity、didSet、get、infix、inout、left、mutating、none、nonmutating、operator、override、postfix、precedence、prefix、right、set、unowned、unowned(safe)、unowned(unsafe)、weak、willSet
变量常量的本质区别
经过上面的学习我们已经能够熟练使用常量和变量了,那么常量和变量的本质区别到底是什么呢?这里通过例子说明一下:
//通过 UIView() 方法创建一个 UIView 的对象(假设系统分配的内存地址为:0x7faa31616bb0)并赋值给申明为 UIView类型 的常量:view0 let view0 : UIView = UIView() //通过 UIView() 方法创建另外一个 UIView 的对象(假设系统分配的内存地址为:0x7f9890c062b0) 并赋值给申明为 UIView类型 的变量:view1 var view1 : UIView = UIView()
第一行代码的意思:首先在内存中的堆区创建一个内存地址为0x7faa31616bb0 的UIView类型的对象,然后在内存中的栈区申明一个名为view0的常量指向该对象,即view0中保存的是0x7faa31616bb0这个地址,而且该常量的值是不可变的(这不废话吗),即view0中保存的内存地址不能变了。
第二行代码的意思: 在堆区又创建一个新的内存地址为0x7f9890c062b0的UIView类型的对象,然后在栈区又申明一个名为view1的变量指向该对象,即view0中保存的是0x7faa31616bb0这个地址,注意此时view1的值是可以改变的,即view1中保存的内存地址是可以变化的。
如果此时执行下面的操作:
//重新创建一个新的 UIView 的对象(假设系统分配的内存地址为:0x7f9890c042b0)并赋值给上面的常量 view0 view0 = UIView()
编译器会报这样的错误:
error: cannot assign to value: 'view0' is a 'let' constant,change 'let' to 'var' to make it mutable
主要是因为创建的新的对象有一个新的内存地址,你把新的对象重新赋值给view0,即view0现在指向另一个对象了,相当于将view0中的原来存储的0x7faa31616bb0内存地址修改成了0x7f9890c042b0,但是view0中存储的内存地址一旦赋值了是不能修改的,所以编译器这里就报错了,他建议你将 let 变成 var 来申明 view0
//重新创建一个新的 UIView 的对象(假设系统分配的内存地址为:0x7f9890c042b0)并赋值给上面的变量 view1 view1 = UIView()
这里是不会报错的,因为view1中保存的内存地址是可以修改的。
但是如果我接着执行下面的代码,编译器会不会报错呢?
view0.backgroundColor = UIColor.white view0.backgroundColor = UIColor.black
两段代码的意思:先将 view0 的背景色设置为白色,然后将view0的背景色修改为黑色(Swift2.0和Swift3.0的修改背景色的方法有所不同,这里使用的是Swift3.0,只是精简了代码,并无本质区别)
答案是不会的,因为在上面的操作中我并没有修改view0中保存的内存地址,只是通过view0中保存的内存地址拿到view0指向的对象,然后修改对象内部的属性(这里是backgroundColor,还可以是frame等等),和 view0 是常量还是变量并没有关系。
总结
常量的值不可修改的的本质是其保存的内存地址不可修改,但是可以通过该地址拿到地址指向的对象并修改对象的属性。
变量的值可以修改的本质是其保存的内存地址可以修改。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
# swift
# 常量
# 定义常量
# 定义变量
# Swift Self详解及简单实例代码
# 详解Swift编程中的常量和变量
# 深入理解swift变量和函数
# Swift中的常量和变量简单概述
# Swift中常量和变量的区别与声明详解
# Swift 常量与变量实例详解
# Swift 4.2使用self做为变量名浅析
# 的是
# 可以使用
# 设置为
# 创建一个
# 还可以
# 背景色
# 所示
# 别无选择
# 报错
# 会报
# 你给
# 有一个
# 你好
# 他们的
# 如果你
# 文档
# 也不
# 是在
# 是因为
# 成了
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
活动邀请函制作网站有哪些,活动邀请函文案?
深入理解Android中的xmlns:tools属性
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
Python数据仓库与ETL构建实战_Airflow调度流程详解
详解jQuery中的事件
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】
Android自定义listview布局实现上拉加载下拉刷新功能
Android滚轮选择时间控件使用详解
Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践
手机网站制作与建设方案,手机网站如何建设?
浅谈Javascript中的Label语句
网站建设整体流程解析,建站其实很容易!
Laravel如何实现事件和监听器?(Event & Listener实战)
如何在万网利用已有域名快速建站?
Laravel如何操作JSON类型的数据库字段?(Eloquent示例)
如何快速生成专业多端适配建站电话?
Laravel路由怎么定义_Laravel核心路由系统完全入门指南
如何在宝塔面板中创建新站点?
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
香港服务器网站生成指南:免费资源整合与高速稳定配置方案
米侠浏览器网页图片不显示怎么办 米侠图片加载修复
Bootstrap CSS布局之列表
重庆市网站制作公司,重庆招聘网站哪个好?
Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置
长沙企业网站制作哪家好,长沙水业集团官方网站?
如何基于PHP生成高效IDC网络公司建站源码?
百度浏览器网页无法复制文字怎么办 百度浏览器复制修复
javascript读取文本节点方法小结
html文件怎么打开证书错误_https协议的html打开提示不安全【指南】
如何在云服务器上快速搭建个人网站?
Firefox Developer Edition开发者版本入口
魔毅自助建站系统:模板定制与SEO优化一键生成指南
Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】
Android仿QQ列表左滑删除操作
如何在搬瓦工VPS快速搭建网站?
Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】
Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】
Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势
教你用AI将一段旋律扩展成一首完整的曲子
*服务器网站为何频现安全漏洞?
Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives
html5的keygen标签为什么废弃_替代方案说明【解答】
,南京靠谱的征婚网站?
Laravel如何配置和使用缓存?(Redis代码示例)
如何挑选最适合建站的高性能VPS主机?
韩国服务器如何优化跨境访问实现高效连接?
如何在建站之星网店版论坛获取技术支持?
java获取注册ip实例
如何在橙子建站上传落地页?操作指南详解

