知识点

  1. 基本概念
  2. 结构体的基本使用
  3. 结构体构造器(构造函数/构造方法)
  4. 结构体扩充函数(方法), 又称成员方法
  5. 结构体是值类型

1. 基本概念

1.1 概念介绍
  • 结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合

  • 结构体(struct)指的是一种数据结构

  • 结构体是值类型,在方法中传递时是值传递

  • Swift中的结构体是一类类型, 可以定义属性和函数(甚至构造函数和析构函数等)

  • 结构体的格式

struct 结构体名称 {
结构体属性和函数
}

2. 结构体的基本使用

2.1 Swift要求实例化一个结构体或类的时候,所有的成员变量都必须有初始值
  • 如果结构体的属性有默认值, 可以直接使用结构体名称()实例化一个结构体
// 所有成员属性都有默认值, 直接使用 结构体名称() 实例化结构体
struct Rect {
var width:Double = 0.0 // 结构体所有成员属性都是有初始值
var height:Double = 0.0
}
var r = Rect() // 所以这里可以直接使用 结构体名称() 实例化结构体
print("width = \(r.width) height = \(r.height)")
//输出结果: width = 0.0 height = 0.0
  • 如果结构体的属性没有默认值, 必须使用逐一构造器实例化结构体
// 如果结构体的属性没有默认值, 必须使用逐一构造器实例化结构体
struct Rect {
var width : Double
var height : Double
}
// 这里必须使用逐一构造器实例化结构体
var r = Rect(width: 10, height: 20)
print("width = \(r.width) height = \(r.height)")
//输出结果: width = 10.0 height = 20.0
  • 结构体属性的访问使用点.语法
struct Rect {
var width:Double = 0.0
var height:Double = 0.0
} var r = Rect()
r.width = 100
r.height = 99
print("width = \(r1.width) height = \(r1.height)")
//输出结果: width = 100.0 height = 99.0
  • 系统结构体的创建方式
// (CGPoint/CGSize/CGRect)
let point = CGPointMake(100, 100)
let point1 = CGPoint(x: 100, y: 100)
let size = CGSizeMake(100, 100)
let size1 = CGSize(width: 100, height: 100)
let rect = CGRectMake(100, 100, 100, 100)
let rect1 = CGRect(x: 0, y: 0, width: 0, height: 0)

3. 结构体构造器(构造函数/构造方法)

  • Swift中的结构体和类跟其它面向对象语言一样都有构造函数, 而OC是没有的
  • Swift要求实例化一个结构体或类的时候,所有的成员变量都必须有初始值,
  • 构造函数的意义就是用于初始化所有成员变量的, 而不是分配内存, 分配内存是系统帮我们做的.
  • 如果结构体中的所有属性都有默认值, 可以使用结构体名称()实例化一个结构体
  • 如果结构体中的属性没有默认值, 可以自定义构造器, 并在构造器中给所有的属性赋值
  • 其实结构体有一个默认的逐一构造器, 用于在初始化时给所有属性赋值
3.1 默认的结构体构造器(函数/方法)
struct Rect2 {
var width:Double
var height:Double = 0.0
}
//逐一构造器
var r2 = Rect2(width: 10.0, height: 10.0);
//错误写法, 顺序必须和结构体中成员的顺序一致
var r2 = Rect2(height: 10.0, width: 10.0);
//错误写法, 必须包含所有成员
var r2 = Rect2(height: 10.0);
3.2 扩充结构体的构造器(函数/方法)
  • 1.默认情况下实例化结构体时,是在调用系统给结构体的提供的一个默认构造函数
  • 2.在一个构造函数执行结束时,是必须保证所有的成员变量都已经被初始化
  • 3.如果扩充了构造函数,并且没有明确的实现系统默认的构造函数,那么扩充的构造函数会覆盖系统默认的构造函数
struct Location {
var x : Double
var y : Double // 由于上面定义结构体属性没有初始化, 所以这个是系统默认的构造函数
init(x : Double, y : Double) { // 明确实现系统默认的构造函数
self.x = x // 这里一定要写上 self , 区分传输参数与成员变量
self.y = y //
} // 这里扩充了构造函数, 如果没有实现系统默认的构造函数,
// 在使用的时候也将没有系统默认的构造函数, 就只有扩充的构造函数
init(x : String, y : String) { // 扩充的构造函数
self.x = Double(x)!
self.y = Double(y)!
// 这里传入的参数, 转化之后是可选类型, 所以必须解包, 可能转化不成功或者为 nil ,
// 因此会导致程序崩溃, 所以最好做判断后再传解包的值, (这里没有写判断)
} init() { // 提供通过 结构体名() 实例化出默认的结构体的函数
x = 0 //self.x = 0 // 这里可以不写 self
y = 0 //self.y = 0
}
} let center = Location()
let center2 = Location(x: 10, y: 10)
let center3 = Location(x: "20", y: "30")
print(center)
print(center2)
print(center3)
// 输出结果:
//Location(x: 0.0, y: 0.0)
//Location(x: 10.0, y: 10.0)
//Location(x: 20.0, y: 30.0)
3.3 "值类型"的构造器代理
  • 构造器代理: 构造方法之间的相互调用
  • 构造方法可以调用其他构造方法来完成实例的构造, 称之为构造器代理
  • 好处: 减少构造方法之间的重复代码
struct Rect1 {
var width:Double
var height:Double
init(width:Double, height:Double){
self.width = width
self.height = height
} init(){
//width = 0
//height = 0
//构造器代理
self.init(width:0 , height:0)
} func show(){
print("width = \(width) height = \(height)")
}
}
var r2 = Rect1()
r2.show()
//输出结果: width = 0.0 height = 0.0 var r3 = Rect1(width: 100, height: 100)
r3.show()
//输出结果: width = 100.0 height = 100.0

4. 结构体扩充函数(方法), 又称成员方法

  • 在C和OC中结构体只有属性, 而Swift中结构体中还可以定义函数(方法)
4.1 给自定义的结构体扩充函数
  • 给自定义的结构体扩充函数,必须在函数前加 mutating
  • 给结构体定义一个函数, 该函数只属于该结构体
  • 结构体中的成员函数必须使用某个实例调用
  • 结构体内部函数可以访问成员属性
struct Location {
var x : Double
var y : Double // 给结构体扩充函数,必须在函数前加 mutating
mutating func moveH(distance : Double) {
x += distance
} mutating func moveV(distance : Double) {
y += distance
} mutating func test() {
print("test")
}
} var center = Location(x: 100, y: 100)
center.moveH(100)
center.moveV(-100)
print(center)
4.2 给系统的结构体扩充方法
  • 必须在系统提供结构体类型前加上extension
extension CGPoint {
mutating func moveH(distance : CGFloat) {
x += distance
}
} var point = CGPoint(x: 100, y: 100)
point.moveH(50)
print(point)
4.3 (补充) 给系统的类扩充方法
  • 使用系统提供的方法
let btn = UIButton()
btn.setTitle("按钮", forState: .Normal)
let title = btn.titleLabel!.text
  • 给系统的提供的类添加方法, 必须在类名前加上 extension关键字
extension UIButton {
func getTitle() -> String? {
return self.titleLabel!.text
}
}
let title1 = btn.getTitle()

5. 结构体是值类型

5.1 结构体变量或常量赋值是值拷贝
  • 结构体是值类型, 结构体之间的赋值其实是将等号=右边的结构体中的值完全拷贝一份到等号=左边的变量或常量
  • 所以结构体间相互赋值是两个不同的实例, 是值拷贝拷贝
struct Rect4 {
var width:Double
var height:Double = 0.0
func show() -> Void{
print("width = \(width) height = \(height)")
}
} var r5 = Rect4(width: 10.0, height: 10.0)
var r6 = r5
r5.show()
r6.show()
r5.width = 20.0
r5.show()
r6.show()
//输出结果:
//width = 10.0 height = 10.0
//width = 10.0 height = 10.0
//width = 20.0 height = 10.0
//width = 10.0 height = 10.0
5.2 结构体常量与存储属性的关系
  • 结构体和枚举是值类型

    • 因此不能修改结构体常量中的属性
    • 不能修改结构体/枚举常量对象中的值, 因为他指向的对象是一个常量
struct Person2 {
var name: String
var age: Int
}
let p2: Person2 = Person2(name: "cdh", age: 20)
//因为结构体是值类型, 所以不能修改结构体常量中的属性
//不能修改结构体/枚举常量对象中的值, 因为他指向的对象是一个常量
//以下写法错误
//p2.name = "CDH" //不能修改结构体常量对象的值
//以下写法错误
//p2 = Person2(name: "CDH", age: 50)
5.3 (补充)类常量与存储属性的关系
  • 类是引用类型

    • 可以修改类常量中属性的值, 因为他指向的对象不是一个常量
class Person3 {
var name: String = "cdh"
var age: Int = 20
}
let p3:Person3 = Person3()
//可以修改类常量中属性的值, 因为他指向的对象不是一个常量
p3.name = "CDH"
//不可以修改类常量的指向
//以下写法是错误的
//p3 = Person4()

Swift超详细的基础语法-结构体,结构体构造器,定义成员方法, 值类型, 扩充函数的更多相关文章

  1. Swift与C#的基础语法比较

    背景: 这两天不小心看了一下Swift的基础语法,感觉既然看了,还是写一下笔记,留个痕迹~ 总体而言,感觉Swift是一种前后端多种语言混合的产物~~~ 做为一名.NET阵营人士,少少多多总喜欢通过对 ...

  2. 【Day1】4.基础语法及分支结构

     视频地址(全部) https://edu.csdn.net/course/detail/26057 课件地址(全部) https://download.csdn.net/download/gentl ...

  3. 3、二、c# 面向对像编程。类,结构、C# 数据类型(引用类型、值 类型、指针类型)、ref参数与out参数、方法的重载、静态类型与静态成员、继承与多态、委托与事件

    一.类 定义类使用class关键字. <access specifier> class class_name { // member variables 成员变量 <access s ...

  4. 超详细Java基础-多态

    茫茫人海千千万万,感谢这一秒你看到这里.希望我的能对你的有所帮助!共勉! 愿你在未来的日子,保持热爱,奔赴山海! Java基础知识(多态) 多态 多态就是指程序中定义的引用变量所指向的具体类型和通过该 ...

  5. 超详细“零”基础kafka入门篇

    1.认识kafka 1.1 kafka简介 Kafka 是一个分布式流媒体平台 kafka官网:http://kafka.apache.org/ (1)流媒体平台有三个关键功能: 发布和订阅记录流,类 ...

  6. Swift - 34 - 闭包的基础语法

    //: Playground - noun: a place where people can play import UIKit // 初始化一个整数数组 var arr = [1, 3, 5, 7 ...

  7. 八皇后问题 递归实现 C语言 超详细 思路 基础

    八皇后问题 :假设 將八个皇后放到国际象棋盘上,使其两两之间无法相互攻击.共有几种摆法? 基础知识: 国际象棋里,棋盘为8X8格. 皇后每步可以沿直线.斜线 走任意格. 思路: 1.想把8个皇后放进去 ...

  8. Python基础语法-内置数据结构之列表

    列表的一些特点: 列表是最常用的线性数据结构 list是一系列元素的有序组合 list是可变的 列表的操作, 增:append.extend.insert 删:clear.pop.remove 改:r ...

  9. Python基础语法04-数据结构

    Python Number(数字) Python Number 数据类型用于存储数值. 数据类型是不允许改变的,这就意味着如果改变 Number 数据类型的值,将重新分配内存空间. Python 支持 ...

随机推荐

  1. [selenium webdriver Java]显示的等待同步

    显示等待可以在执行下一次操作时,自定义等待条件 显示的等待只需要执行在需要同步的地方而不影响脚本的其他地方 Selenium WebDriver提供了WebDriverWait和ExpectedCon ...

  2. 设计模式_Proxy_代理模式

    形象例子: 跟MM在网上聊天,一开头总是“hi,你好”,“你从哪儿来呀?”“你多大了?”“身高多少呀?”这些话,真烦人,写个程序做为我的Proxy吧,凡是接收到这些话都设置好了自动的回答,接收到其他的 ...

  3. windows 下Python import 导入自定义模块

    周末在家研究这个东西,则找到解决方案. 费话少说,上代码 #定义一个自定义的函数,如下 #函数的名称必须是字母和数字的组合,不能用数字开头 #函数名后用小括号括住入参,可以用逗号分隔多个 #如果有返回 ...

  4. windows串口通信的一个活动图

    1,打开串口的活动图: 2,关闭串口的活动图:

  5. 50道经典的JAVA编程题 (11-15)

    50道经典的JAVA编程题 (11-15),新年的第一天,继续啦...\(^o^)/~,这50道题都跨年了啊...哈哈 [程序11] TestTN.java 题目:有1.2.3.4个数字,能组成多少个 ...

  6. USB模式安装CentOS6.4_minimal

    首先说明一下我遇到的3个问题 1. 由于机器没有光驱,所以只能USB安装 2.由于CentOS5.0+才对USB安装支持比较好,所以USB安装,建议安装CentOS5.0+以上的版本 3.由于FAT3 ...

  7. dataStructure@ Binary Search Tree

    #include<iostream> #include<cstdio> #include<cstring> #include<limits> #incl ...

  8. C# 多个个Dictionary合并更优雅的写法

    Dictionary 现在有两个Dictionary的对象,想把两个对象的中数据合并成一个. 使用for循环的话觉得非常不合适,于是考虑是否有相应的方法,网上找了很多,都是for循环,最后终于找到了一 ...

  9. MySQL Workbench 导出数据库脚本(图文)

    1.如下图红框所示,在Server Administration那里,点击"New Server Instance" 2.如下图所示,如果是连接本地数据库,则选localhost, ...

  10. iOS开发-在表单元中添加子视图

    #import <UIKit/UIKit.h> @interface NameAndColorCellTableViewCell : UITableViewCell @property(c ...