版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/twlkyao/article/details/34855597

    在Swift中,结构体和枚举类型为值类型(Structures and Enumerations),在Stack Overflow上有这样一个问题:结构体中的可变属性仅仅有在使用mutating关键字之后才干被内置的方法改动(假设是不可变属性肯定不能够改动了。这就不用纠结了。只是在Swift中。另一个例外。那就是构造器Initialization对于结构体和类的常量实例属性能够在构造器中进行设置,这感觉有点违背常量属性的含义,细致想想也能够理解,由于实例化的时候,最后调用的是构造器。所以在构造器之后,实例属性的值才确定)。

    @Author: twlkyao 转载或者引用请保留此行。

    这里梳理下缘由,有什么不正确的地方还望指出,在解决问题之前,有两个概念须要解释。

    首先,一个值是不是能够改动并不在于它是什么类型(类还是结构体)。而在于它的存储类型(常量还是变量)。仅仅有变量才干够进行改动。

    然后,值类型能够理解为每一个属性都在内存中有自己的一份空间,和其他的实例之间的属性是没有关系的,值类型能够理解为一个连续的代码块,每创建一个值类型的实例,就相当于将这种代码块复制了一份,每一份都有自己的对应的属性的值,假设实例类型是可变的,那么这个代码块中的每一个属性都是能够变的。假设一个实例类型是不可变的。那么这个代码块中的每一个属性也都是不可变的,每一个实例类型都必须能够支持属性可变和不可变,为了满足这个条件,Swift将结构体的方法分为两类,能够改动结构体结构的和不能够改动结构体结构的。改动结构体结构的方法,必须被可变的结构体实例调用。不改动结构体结构的方法,能够被可变和不可变的结构体实例调用,而大多数情况下,使用的是后者,所以有可能苹果直接将后者作为默认情况,结构体的方法不能够改动结构体实例的属性

引用类型。能够理解为指针(尽管Swift中没有指针,就像Java一样,可是面向对象的语言实际上是把类实例都当指针处理的)。指向内存空间中的同一个位置,每创建一个引用类型的实例,就会多一个指针,指向这个内存地址。

    好了。下边来解决问题,由于值类型实例能够赋值给变量或者常量,而被赋值的常量或者变量又决定了值类型实例是否可变,进而决定了值类型的实例属性是否可变。能够理解为值类型的实例属性有两种模式,可变和不可变(由属性的类型和最后被实例赋值的常量或变量决定),以下是规则:

    举比例如以下:

struct Point {
var x = 0
let y = 0
} var a = Point()
let b = Point() a.x = 1 // var, right.
//a.y = 2 // let, compile time error.
//b.x = 3 // let, compile time error.
//b.y = 4 // let, compile time error.

    如上所看到的,仅仅有在实例属性为变量。而且终于实例赋值给一个变量的时候,才干够改动对应变量的属性。而引用类型在实例化的时候,并没有进行对应的属性的复制,仅仅是相当于加入了一个指向对应属性的指针,而属性可能又是指向其他类型的指针,所以var类型的属性还是let类型的属性。仅仅是确定这个"指针"也就是对应关系是不是能够变

    能够理解为在结构体进行实例化之前,结构体并不知道自己是不是可变的,为了防止被误改动,默觉得自己是不可变的,除非在事先声明的情况才可变,这就是"mutating"关键字的作用。

    以下给出代码说明值类型。

struct Point1 {
var x = 0, y = 0
mutating func moveToX(x: Int, andY y:Int) { // need to be a mutating method in order to work
self.x = x
self.y = y
}
} var p1 = Point1(x: 1, y: 2) // in order to change the properties, you have to use var, since it is a value type.
p1.x = 3 // works from outside the struct.
p1.moveToX(5, andY: 5) println("p1.x = \(p1.x), p1.y = \(p1.y)") /***************************/
struct Point2 {
let x = 0, y = 0
} var p2 = Point2(x: 1, y: 2)
println("p2.x=\(p2.x), p2.y=\(p2.y)")
//p2.x = 3 // can't change p2.x, since p2.x is a constant.

    以下给出代码,说明引用类型:

class Point3 {
var x = 0
var y = 0
let plet: Point4
var pvar: Point4
init(x: Int, y: Int) {
self.x = x
self.y = y
self.plet = Point4() // plet.x = 0, plet.y = 0
self.pvar = Point4() // pvar.x = 0, pvar.y = 0
} func moveToX(x: Int, andY y: Int) { // no need to use "mutating" keyword.
self.x = x;
self.y = y;
}
} class Point4 {
var x = 0
var y = 0
} let p3 = Point3(x:1, y:2) // you can use let, even though you want to change the property, because it is a reference.
p3.x = 2
p3.moveToX(5, andY: 5) // no need to use the "mutating" keyword.
println("p3.x = \(p3.x), p3.y = \(p3.y)") // x = 5, y = 5 var p4 = p3 // p3 and p4 are the same, since they are reference type.
p4.x = 3
println("p4.x = \(p4.x), p4.y = \(p4.y)") // p4.x = 3, p4.y = 5
println("p3.x = \(p3.x), p3.y = \(p3.y)") // p3.x = 3, p3.y = 5 /**********************/
p3.plet.x = 4
println("p4.p.x = \(p3.plet.x), p4.p.y = \(p3.plet.y)") // p3.plet.x = 4, p3.plet.y = 0 let p5 = Point4()
//p3.plet = p5 // can't assign new value to p3.plet since the realtion can't change since the p property of p3 is a constant.
p3.pvar = p5 // even p3 is a constant, its propery can change.

    在上面的代码中,最重要的就是"*"号以下的代码。能够说明引用类型中的let和var的作用。

    更具体讨论,能够查看:http://stackoverflow.com/questions/24035648/swift-and-mutating-struct

Swift——(六)Swift中的值类型的更多相关文章

  1. Windows Phone 开发起步之旅之二 C#中的值类型和引用类型

    今天和大家分享下本人也说不清楚的一个C#基础知识,我说不清楚,所以我才想把它总结一下,以帮助我自己理解这个知识上的盲点,顺便也和同我一样不是很清楚的人一起学习下.  一说起来C#中的数据类型有哪些,大 ...

  2. C#中的值类型(value type)与引用类型(reference type)的区别

    ylbtech- .NET-Basic:C#中的值类型与引用类型的区别 C#中的值类型(value type)与引用类型(reference type)的区别 1.A,相关概念返回顶部     C#中 ...

  3. C# 中的值类型和引用类型

    原文 C# 中的值类型和引用类型 值类型(value type):int,long,float,double,decimal,char,bool 和 struct 统称为值类型.值类型变量声明后,不管 ...

  4. C++ : 从栈和堆来理解C#中的值类型和引用类型

    C++中并没有值类型和引用类型之说,标准变量或者自定义对象的存取默认是没有区别的.但如果深入地来看,就要了解C++中,管理数据的两大内存区域:栈和堆. 栈(stack)是类似于一个先进后出的抽屉.它的 ...

  5. C#中的值类型和引用类型,深拷贝,浅拷贝

    from https://www.jianshu.com/p/2d27b06e253f 一.C#中的值类型和引用类型 概念 值类型直接存储其值. 引用类型存储对值的引用. 说起来有些拗口,其本质是Va ...

  6. 浅谈C#中的值类型和引用类型

    在C#中,值类型和引用类型是相当重要的两个概念,必须在设计类型的时候就决定类型实例的行为.如果在编写代码时不能理解引用类型和值类型的区别,那么将会给代码带来不必要的异常.很多人就是因为没有弄清楚这两个 ...

  7. 【.Net】浅谈C#中的值类型和引用类型

    在C#中,值类型和引用类型是相当重要的两个概念,必须在设计类型的时候就决定类型实例的行为.如果在编写代码时不能理解引用类型和值类型的区别,那么将会给代码带来不必要的异常.很多人就是因为没有弄清楚这两个 ...

  8. .NET中的值类型与引用类型

    .NET中的值类型与引用类型 这是一个常见面试题,值类型(Value Type)和引用类型(Reference Type)有什么区别?他们性能方面有什么区别? TL;DR(先看结论) 值类型 引用类型 ...

  9. Swift 中的值类型与引用类型

    顶级修饰 次级修饰 赋值类型 存储类型 值类型 值类型   深拷贝 栈 值类型 引用类型 浅拷贝 堆 引用类型 值类型 浅拷贝 堆 引用类型 引用类型 浅拷贝 堆 复合引用类型会改变内部值类型的存储行 ...

随机推荐

  1. mpvue 无法获取$store的问题

    在开发的时候,我们喜欢将一些公共的方法,属性,放在一个特定的位置,例如在mpvue开发小程序的时候, 我们将其放在 vue提供的store里面,或者在mainjs中通过Vue.prototype.xx ...

  2. Solr的学习使用之(三)IKAnalyzer中文分词器的配置

    1.为什么要配置? 1.我们知道要使用Solr进行搜索,肯定要对词语进行分词,但是由于Solr的analysis包并没有带支持中文的包或者对中文的分词效果不好,需要自己添加中文分词器:目前呼声较高的是 ...

  3. 【知识强化】第五章 中央处理器 5.1 CPU的功能和基本结构

    那么在前四章我们已经把数据的表示和运算,存储系统和指令系统都已经给大家讲完了.那么从这一章开始,我们将要讲解中央处理器的内容.那么这一部分内容我们就进入到我们计算机组成原理的一个深水区,它是我们计算机 ...

  4. 导入excle到服务器时候删除服务器历史数据

    //删除历史数据EXCLE 当天前一天的数据都删除 var folder = Path.GetDirectoryName(absFilePath); var files = Directory.Get ...

  5. iconfont图标symbol引用方式,有的图标不能通过设置color样式来修改颜色的解决办法

    现象:iconfont安装后的图标,是通过symbol引用方式,有的图标不能通过color修改颜色的解决办法,有的又可以. <svg class="icon" aria-hi ...

  6. Linux就该这么学07学习笔记

    参考链接:https://www.linuxprobe.com/chapter-07.html RAID磁盘冗余阵列 RAID 0 RAID 0技术把多块物理硬盘设备(至少两块)通过硬件或软件的方式串 ...

  7. setup PC not sleep when turn off display

  8. Vue-系统修饰键

    可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器. .ctrl .alt .shift .meta 例如: 例如: <!-- Alt + C --> <input ...

  9. 带有IBM大脑的浮动机器人被成功引导至太空

    近日,带有IBM大脑的浮动机器人被成功引导至太空,在接下来的装运前往国际空间站包近三吨的研究和再补给材料. 机器人的全名是CrewInteractiveMobileCompanion:Cimon.它看 ...

  10. Gitbook环境搭建及制作——2019年10月24日

    1.gitbook介绍 GitBook 是一个基于 Node.js 的命令行工具,支持 Markdown 和 AsciiDoc 两种语法格式,可以输出 HTML.PDF.eBook 等格式的电子书.可 ...