Swift超详细的基础语法-结构体,结构体构造器,定义成员方法, 值类型, 扩充函数
知识点
- 基本概念
- 结构体的基本使用
- 结构体构造器(构造函数/构造方法)
- 结构体扩充函数(方法), 又称成员方法
- 结构体是值类型
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超详细的基础语法-结构体,结构体构造器,定义成员方法, 值类型, 扩充函数的更多相关文章
- Swift与C#的基础语法比较
背景: 这两天不小心看了一下Swift的基础语法,感觉既然看了,还是写一下笔记,留个痕迹~ 总体而言,感觉Swift是一种前后端多种语言混合的产物~~~ 做为一名.NET阵营人士,少少多多总喜欢通过对 ...
- 【Day1】4.基础语法及分支结构
视频地址(全部) https://edu.csdn.net/course/detail/26057 课件地址(全部) https://download.csdn.net/download/gentl ...
- 3、二、c# 面向对像编程。类,结构、C# 数据类型(引用类型、值 类型、指针类型)、ref参数与out参数、方法的重载、静态类型与静态成员、继承与多态、委托与事件
一.类 定义类使用class关键字. <access specifier> class class_name { // member variables 成员变量 <access s ...
- 超详细Java基础-多态
茫茫人海千千万万,感谢这一秒你看到这里.希望我的能对你的有所帮助!共勉! 愿你在未来的日子,保持热爱,奔赴山海! Java基础知识(多态) 多态 多态就是指程序中定义的引用变量所指向的具体类型和通过该 ...
- 超详细“零”基础kafka入门篇
1.认识kafka 1.1 kafka简介 Kafka 是一个分布式流媒体平台 kafka官网:http://kafka.apache.org/ (1)流媒体平台有三个关键功能: 发布和订阅记录流,类 ...
- Swift - 34 - 闭包的基础语法
//: Playground - noun: a place where people can play import UIKit // 初始化一个整数数组 var arr = [1, 3, 5, 7 ...
- 八皇后问题 递归实现 C语言 超详细 思路 基础
八皇后问题 :假设 將八个皇后放到国际象棋盘上,使其两两之间无法相互攻击.共有几种摆法? 基础知识: 国际象棋里,棋盘为8X8格. 皇后每步可以沿直线.斜线 走任意格. 思路: 1.想把8个皇后放进去 ...
- Python基础语法-内置数据结构之列表
列表的一些特点: 列表是最常用的线性数据结构 list是一系列元素的有序组合 list是可变的 列表的操作, 增:append.extend.insert 删:clear.pop.remove 改:r ...
- Python基础语法04-数据结构
Python Number(数字) Python Number 数据类型用于存储数值. 数据类型是不允许改变的,这就意味着如果改变 Number 数据类型的值,将重新分配内存空间. Python 支持 ...
随机推荐
- Query Profiler 和Explain 用法详解
一.Query Profiler MySQL 的Query Profiler 是一个使用非常方便的Query 诊断分析工具,通过该工具可以获取一条Query 在整个执行过程中多种资源的消耗情况,如C ...
- toastr
$(function(){ //参数设置,若用默认值可以省略以下面代 toastr.options = { "closeButton": false ...
- Amoeba搞定mysql主从读写分离
前言:一直想找一个工具,能很好的实现mysql主从的读写分离架构,曾经试用过mysql-proxy发现lua用起来很不爽,尤其是不懂lua脚本,突然发现了Amoeba这个项目,试用了下,感觉还不错,写 ...
- 方格取数(1)(HDU 1565状压dp)
题意: 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大. 分析:直接枚举 ...
- js实现收缩菜单效果
废话不多说,直接上代码: 有注释 <head> <title></title> <style type="text/css"> di ...
- HTML5学习之FileReader接口
http://blog.csdn.net/zk437092645/article/details/8745647 用来把文件读入内存,并且读取文件中的数据.FileReader接口提供了一个异步API ...
- sql-表值函数tvf
带有参数的视图 create function fn_fenye (@count as int,@page as int) returns table as return select * from ...
- Discuz资料整理
1.截取字符串:messagecutstr(strip_tags($post['message']), 160);
- Mongodb集群部署ReplicaSet+Sharding -摘自网络
网上关于三种集群方式的搭建方式很多,都是分开来介绍的.Replica Set (复制集成)主要是做主从库的,但是没法实现负载均衡的效果,真正实现这个的,是Sharding(分片集群),通过数据分布在每 ...
- eclipse配置struts.xml自动提示
a)window – preferences – xml - xml catalog –> add b)选择key type为URI c)key: http://struts.apache.o ...