当前位置: 首页 > news >正文

【Swift学习】Swift编程之旅---类和结构体(十三)

  与其他编程语言所不同的是,Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件。你所要做的是在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口。

  注意:通常一个类的实例被称为对象。然而在Swift 中,类和结构体的关系要比在其他语言中更加的密切,本章中所讨论的大部分功能都可以用在类和结构体上。因此,我们会主要使用实例而不是对象。

 

  比较类和结构体

  类和结构体都具有以下特性:

  • 定义用于存储值的属性
  • 定义提供特定能力或功能的方法
  • 定义提供使用下标语法访问值的下标
  • 定义设置初始状态的初始化方法
  • 通过扩展以增加默认实现的功能
  • 符合协议提供某种标准功能

 

  类还具有结构体没有的功能,如下:

  • 继承使一个类具有另一个类的特性
  • 类型转换允许在运行时检查和解释一个类实例的类型
  • 反初始化允许一个类实例释放任何其所被分配的资源
  • 引用计数允许对一个类的多次引用

注意:结构体总是通过被复制的方式在代码中传递,因此请不要使用引用计数。

 

  定义语法

  使用class关键字来申明一个类,使用struct关键字来申明一个结构体。

class SomeClass { 
} 
struct SomeStructure { 
} 

 

注意:类和结构体名称以大写字母开头,属性和方法名称以小写字母开头。

示例如下

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

 在上面的示例中我们定义了一个名为Resolution的结构体,用来描述一个显示器的像素分辨率。这个结构体包含了两个名为width和height的储存属性。储存属性是捆绑和储存在类或结构体中的常量或变量。当这两个属性被初始化为整数0的时候,它们会被推断为Int类型。个名为VideoMode的类,用来描述一个视频显示器的特定模式。这个类包含了四个储存属性变量。第一个是分辨率,它被初始化为一个新的Resolution结构体的实例,具有Resolution的属性类型。新VideoMode实例同时还会初始化其它三个属性,它们分别是,初始值为false(意为“non-interlaced video”)的inteflaced,回放帧率初始值为0.0的frameRate和值为可选String的name。name属性会被自动赋予一个默认值nil,意为“没有name值”,因它是一个可选类型。

  类和结构体实例

   Resolution结构体和VideoMode类的定义仅描述了什么是Resolution和VideoMode。它们并没有描述一个特定的分辨率(resolution)或者视频模式(video mode)。为了描述一个特定的分辨率或者视频模式,我们需要创建一个它们的实例。如下

let someResolution = Resolution() 
let someVideoMode = VideoMode()

 

 过这种方式所创建的类或者结构体实例,其属均会被初始化为默认值。

 

  属性访问

使用点语法访问实例中所含有的属性。其语法规则是,实例名后面紧跟属性名,两者通过点号(.)连接:

println("The width of someResolution is \(someResolution.width)")

 

 你也可以访问子属性,如何VideoMode中Resolution属性的width属性:

println("The width of someVideoMode is \(someVideoMode.resolution.width)") 

 

 你也可以使用点语法为属性变量赋值

someVideoMode.resolution.width = 12880 
println("The width of someVideoMode is now \(someVideoMode.resolution.width)") 

 

 注意:与 Objective-C 语言不同的是,Swift 允许直接设置结构体属性的子属性。上面的最后一个例子,就是直接设置了someVideoMode中resolution属性的width这个子属性,以上操作并不需要从新设置resolution属性。

 

   逐个成员初始化器的结构类型

 所有结构体都有一个自动生成的成员逐一初始化方法,用于初始化新结构体实例中成员的属性。新实例中各个属性的初始值可以通过属性的名称传递到成员逐一初始化器之中:

let vga = resolution(width:640, heigth: 480 

 

 与结构体不同,类实例没有默认的成员逐一初始化器。

 

  结构体和枚举是值类型

个值类型是一个值,当它被分配给一个变量或常量时,或当它被传递给函数时,它的值是被复制的,这意味着它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制。

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

在以上示例中,声明了一个名为hd的常量,其值为一个初始化为全高清视频分辨率(1920 像素宽,1080 像素高)的Resolution实例。

然后示例中又声明了一个名为cinema的变量,其值为之前声明的hd。因为Resolution是一个结构体,所以cinema的值其实是hd的一个拷贝副本,而不是hd本身。尽管hd和cinema有着相同的宽(width)和高(height)属性,但是在后台中,它们是两个完全不同的实例。

 

  类是引用类型

与值类型不同,引用类型在被赋予到一个变量,常量或者被传递到一个函数时,操作的并不是其拷贝。因此,引用的是已存在的实例本身而不是其拷贝

 

  恒等运算符

因为类是引用类型,有可能有多个常量和变量在后台同时引用某一个类实例。如果能够判定两个常量或者变量是否引用同一个类实例将会很有帮助。为了达到这个目的,Swift 内建了两个恒等运算符:

等价于 ( === )

不等价于 ( !== )

if tenEighty === alsoTenTighty { 
    println("tenTighty and alsoTenEighty refer to the same Resolution instance.") 
} 

 

 

  指针

  如果你有 C,C++ 或者 Objective-C 语言的经验,那么你也许会知道这些语言使用指针来引用内存中的地址。一个 Swift 常量或者变量引用一个引用类型的实例与C语言中的指针类似,不同的是并不直接指向内存中的某个地址,而且也不要求你使用星号(*)来表明你在创建一个引用。Swift 中这些引用与其它的常量或变量的定义方式相同。

 

相关文章:

  • 源代码的下载和编译
  • SSH的整合
  • 项目重构之数据源配置与优化:log4j 配置数据库连接池Druid,并实现日志存储到数据库...
  • Java---常用基础面试知识点
  • 对Java中接口和抽象类的理解
  • HTML表格修饰1
  • 使用xib封装一个自定义view的步骤
  • 一道简单的笔试题
  • c# 程序调试出现“未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序。”...
  • CDH(Cloudera)与hadoop(apache)对比
  • IntelliJ IDEA 配置Jetty
  • Spring Cache 介绍
  • WebService应用:音乐站图片上传
  • Linux:信号(上)
  • NYOJ-301递推求值
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • django开发-定时任务的使用
  • exif信息对照
  • Facebook AccountKit 接入的坑点
  • Hibernate【inverse和cascade属性】知识要点
  • Node 版本管理
  • node-glob通配符
  • React-Native - 收藏集 - 掘金
  • Service Worker
  • tweak 支持第三方库
  • vue-router的history模式发布配置
  • windows下使用nginx调试简介
  • Yeoman_Bower_Grunt
  • zookeeper系列(七)实战分布式命名服务
  • 诡异!React stopPropagation失灵
  • 记一次删除Git记录中的大文件的过程
  • 来,膜拜下android roadmap,强大的执行力
  • 消息队列系列二(IOT中消息队列的应用)
  • Java总结 - String - 这篇请使劲喷我
  • RDS-Mysql 物理备份恢复到本地数据库上
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • #HarmonyOS:Web组件的使用
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • #Ubuntu(修改root信息)
  • #单片机(TB6600驱动42步进电机)
  • (16)Reactor的测试——响应式Spring的道法术器
  • (C++)八皇后问题
  • (二开)Flink 修改源码拓展 SQL 语法
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (转) 深度模型优化性能 调参
  • (转)重识new
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例