Swift 3.0基础学习之类与结构体

前言

和其他语言不同的是,Swift不需要为自定义的类和结构体创建接口和实现文件。只需要创建单一文件用来创建类和结构体,其他的外部接口的代码系统会自动生成。下面这篇文章主要介绍了关于Swift 3.0类与结构体的内容,感兴趣的朋友一起来看看吧。

类和结构体区别

Swift的类和结构体具有以下相同的特点:

  • 可以定义属性来保存值
  • 可以定义方法来提供功能
  • 可以定义下标来使用他们的值
  • 可以定义初始化器来配置他们的初始化状态
  • 可以在默认的实现上扩展他们的功能
  • 遵从协议来提供标准的功能

类具有结构体没有的额外的功能:

  • 继承允许某一个类继承另外一个类的特性
  • 类型转换允许你检查并在运行时解释一个类实例的类型
  • 析构器允许释放所有该类已经赋值的实例资源
  • 引用计数允许多个引用一个类的实例

结构体一般来说赋值的时候是直接拷贝的,没有使用引用计数的机制。

符号定义

下面是一个定义结构体和类的例子:

struct Resolution {
 var width = 0
 var height = 0
}
class VideoMode {
 var resolution = Resolution()
 var interlaced = false
 var frameRate = 0.0
 var name: String?
}

结构体初始化的时候可以直接

let vga = Resolution(width: 640, height: 480)

这点和类不一样,类没有默认的逐个成员的初始化器。

结构体和枚举是值类型

let hd = Resolution(width: 1920, height: 1080)
var cinema = hd

再赋值

cinema.width = 2048

结果

print("cinema is now \(cinema.width) pixels wide")
// Prints "cinema is now 2048 pixels wide"

然而hd.width还是1920

print("hd is still \(hd.width) pixels wide")
// Prints "hd is still 1920 pixels wide"

可见赋值过程是做了一次深度拷贝。

枚举也是具有同样的行为, 如以下例子,rememberedDirection的值并没有改变:

enum CompassPoint {
 case north, south, east, west
}
var currentDirection = CompassPoint.west
let rememberedDirection = currentDirection
currentDirection = .east
if rememberedDirection == .west {
 print("The remembered direction is still .west")
}
// Prints "The remembered direction is still .west"

类是引用类型

例如:

let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0

进行赋值引用

let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0

结果

print("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
// Prints "The frameRate property of tenEighty is now 30.0"

标识符

  • 完全相同(===)
  • 不完全相同(!===)
if tenEighty === alsoTenEighty {
 print("tenEighty and alsoTenEighty refer to the same VideoMode instance.")
}
// Prints "tenEighty and alsoTenEighty refer to the same VideoMode instance."

完全相同(===)和等于(==)是不一样的:

  • 完全相同意思是两个类类型的常量或者变量指向完全相同的类实例
  • 等于意思是两个实例被认为值相同或者相等, 可以自行定义==操作符来进行判断两个实例在某种意义上是相等的

选择使用类和结构体

由于结构体的实例一般是值传递,而类实例一般是引用传递,因此你需要根据实际情况来考虑应该定义一个类还是结构体.

如有以下一种或多仲情况使用结构体:

  • 结构体主要的目的是封装少量的相关性简单数据值
  • 在结构体的实例赋值或者传递的时候,需要考虑到封装好的值会被拷贝而不是引用是否是合理的
  • 任何保存于结构体的属性都是值类型的,他们也是期望被赋值或者传递时是拷贝而不是引用
  • 结构体不需要从其他存在的类型继承属性或者行为

看看几个使用结构体恰当的例子:

  • 几何图形的大小,可以封装width和height属性,都是Double类型
  • 指向连续序列范围的方法,可以封装start和length属性,都是Int类型
  • 一个在3D坐标系统的点, 可以封装x, y和z属性,都是Double类型

其他的情况请定义类并创建类实例,管理和传递都使用引用。

在实践中,大部分的自定义数据结构都是使用类居多,很少使用结构体。

String、Array和Dictionary的赋值和拷贝行为

String, Array和 Dictionary都是结构体,因此赋值直接是拷贝,而NSString, NSArray 和NSDictionary则是类,所以是使用引用的方式。

参考英语原文:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-ID82

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • 详解Swift语言中的类与结构体

    类 在 Swift 中类是建立灵活的构建块.类似于常量,变量和函数,用户可以定义的类的属性和方法.Swift给我们提供了声明类,而无需用户创建接口和实现文件的功能.Swift 允许我们创建类作为单个文件和外部接口,将默认在类一次初始化来创建. 使用类的好处: 继承获得一个类的属性到其他类 类型转换使用户能够在运行时检查类的类型 初始化器需要处理释放内存资源 引用计数允许类实例有一个以上的参考 类和结构的共同特征: 属性被定义为存储值 下标被定义为提供访问值 方法被初始化来改善功能 初始状态是由初

  • Swift中的类class与结构体struct体学习笔记

    一.引言 Swift中的类与结构体十分相似,和Objective-C不同的事,Swift中的结构体不仅可以定义属性,也可以像类一样为其定义方法. Swift中的类与结构体有如下相似点: 1.定义属性来存储值. 2.定义函数来提供功能. 3.通过定义下标语法使用下标的方式取值. 4.定义构造方法来对其进行初始化. 5.通过扩展来在原始基础上添加功能. 6.通过协议来定义实现标准. 当然类和结构体也有许多不同点,下面这些功能是类独有的,结构体没有: 1.通过继承来创建类的子类. 2.在运行时允许对类

  • Swift 3.0基础学习之类与结构体

    前言 和其他语言不同的是,Swift不需要为自定义的类和结构体创建接口和实现文件.只需要创建单一文件用来创建类和结构体,其他的外部接口的代码系统会自动生成.下面这篇文章主要介绍了关于Swift 3.0类与结构体的内容,感兴趣的朋友一起来看看吧. 类和结构体区别 Swift的类和结构体具有以下相同的特点: 可以定义属性来保存值 可以定义方法来提供功能 可以定义下标来使用他们的值 可以定义初始化器来配置他们的初始化状态 可以在默认的实现上扩展他们的功能 遵从协议来提供标准的功能 类具有结构体没有的额

  • Swift 3.0基础学习之扩展

    介绍 扩展可以为类,结构体,枚举和协议添加新的功能.包括可以对没有源码访问权限的类型进行扩展.扩展和 Objective-C 分类 的概念类似.(和 Objective-C 的分类不一样的是,Swift 扩展没有名称). 在 Swift 中,扩展可以做到: 添加计算的实例属性和计算的类型属性 定义实例方法和类型方法 提供新的初始化器 定义下标 定义并使用新的嵌套类型 使现有类型符合协议 值得注意的是:扩展可以为类型添加功能,但是不可以重写现有的功能. 扩展语法 使用关键字 extension 定

  • Swift 3.0基础学习之下标

    前言 类,结构体和枚举都可以定义下标,使用下标可以快速访问集合,列表或者序列的数据成员元素.可以使用someArray[index]来访问Array, 使用someDictionary[key]来访问Dictionary. 一个类型可以定义多个下标. 定义一个get set的下标: subscript(index: Int) -> Int { get { // return an appropriate subscript value here } set(newValue) { // perf

  • Swift 3.0基础学习之闭包

    前言 闭包是功能性自包含模块,可以在代码中被传递和使用. Swift 中的闭包与 C 和 Objective-C中的 blocks 以及其他一些编程语言中的 lambdas 比较相似.下面这篇文章就来详细介绍了关于Swift 3.0中的闭包,感兴趣的一起来看看吧. 开始 闭包的书写格式如下: { (parameters) -> return type in statements } 如 reversedNames = names.sorted(by: { (s1: String, s2: Str

  • Swift 3.0基础学习之枚举类型

    枚举语法 使用关键字 enum 定义一个枚举 enum SomeEnumeration { // enumeration definition goes here } 例如,指南针有四个方向: enum CompassPoint { case north case south case east case west } 这里跟 c 和 objective-c 不一样的是,Swift 的枚举成员在创建的时候没有给予默认的整型值.所以上面代码中的东南西北并不是0到3,相反,不同的枚举类型本身就是完全

  • 0基础学习前端开发的一些建议

    以下纯属个人观点和建议,肯定是有局限性的,但是也希望能给你带来一些帮助. 我们俨然能感受到前端岗位现在已经发展成了最重要的研发岗位之一,所以多我们提出的要求也就越来越高了.所以我们需要的也就不仅仅只是掌握css.html.JavaScript了,但是这三大件一直都是前端的根本,这一点从未改变,而这三大件中JavaScript又是重中之重. 接下来我会结合我的一点经验,给出前端系统学习路线的一些具体建议以及入门前端时的一些困境. 入门前端时的一些困境 1.因一些基础算法.数据结构理论不扎实导致一些

  • Go语言学习教程之结构体的示例详解

    目录 前言 可导出的标识符 嵌入字段 提升 标签 结构体与JSON相互转换 结构体转JSON JSON转结构体 练习代码步骤 前言 结构体是一个序列,包含一些被命名的元素,这些被命名的元素称为字段(field),每个字段有一个名字和一个类型. 结构体用得比较多的地方是声明与数据库交互时需要用到的Model类型,以及与JSON数据进行相互转换.(当然,项目中任何需要多种数据结构组合在一起使用的地方,都可以选择用结构体) 代码段1:声明一个待办事项的Model类型: type Todo struct

  • Go语言结构体Go range的学习教程

    目录 正文 Go Range 正文 在前一篇博客我们学习了 Go 数组,其要求所有元素为同一数据类型,如果希望存储不同类型的数据,就要用到结构体相关知识. 结构体的定义:存储相同或不同类型的数据集合. 有 C 相关经验,结构体还是比较容易理解的,语法格式如下所示: type struct_variable_type struct { member definition member definition ... member definition } 上述语法格式的关键字是 struct 和 t

  • C语言结构体数组同时赋值的另类用法

    说到C语言结构体数组的同时赋值,许多人一想就会想到用以下的这种方法,咱们来写一个例子: #include <stdio.h> struct student { int a; int b ; int c ; }; struct student array1[1000] ; int main(void) { int i ; for(i = 0 ; i < 1000 ; i++) { array[i].a = 1 ; array[i].b = 2 ; array[i].c = 3 ; } fo

  • Go语言空结构体详解

    目录 前言 什么是空结构体 特点 地址相同 大小为0 原理探究 使用场景 集合(Set) channel中信号传输 总结 前言 在使用 Go 语言开发过程中,我们不免会定义结构体,但是我们定义的结构体都是有字段的,基本不会定义不包含字段的 空结构体.你可能会反过来问,没有字段的空结构体有什么用呢?那么我们这篇文章就来研究下空结构体吧! 注:本文基于go 1.14.4 分析 什么是空结构体 我们说不包含任何字段的结构体叫做空结构体,可以通过如下的方式定义空结构体: 原生定义 var a struc

随机推荐