Swift 基本语法2
一、?和!
1、可选类型: ?
在swift中,可选类型(?)其根源是一个枚举型,里面有None和Some两种类型。其实所谓的nil就是Optional.None, 非nil就是Optional.Some.
! 代表强制解包
// MARK: - ?和!
// ?代表可选类型,实际上的值是枚举类型 -- None和Some,其实nil值相当于Optional.None,非nil就是Optional.Some
// !代表强制解包 // 定义一个Int类型的可选类型变量
var num : Int? =
// 把这个类型类型的变量赋值给另一个可选类型的变量
var num1 = num
print(num1)
// 打印出来以后是一个Optional类型的值,如果要取到8,必须对可选类型强制解包!
var num2 = num!
print(num2) var number : Int?
// 如果对没值(nil)的变量进行强制解包,会造成程序崩溃
//var number1 = number!
2、可选绑定
可选类型分为有值和没值,如果可选类型的变量没值时对其强制解包,程序就会崩溃 。所以,强制解包是非常危险的
var number : Int?
// 如果对没值(nil)的变量进行强制解包,会造成程序崩溃
//var number1 = number! // 可选绑定
// 如果不确定可选类型变量是否有值时,用可选绑定,不需要对可选类型强制解包
if var number2 = number {
print(number2)
}
3、隐式解析可选类型
隐式解析可选类型和可选类型一样,都是有值和没值(nil)两种结果,区别是赋值时,隐式解析可选类型不需要强制解包。
// 隐式解析可选类型:有值,没值(nil) var intNum : Int! =
var intNum1 = intNum
print(intNum)
print(intNum1) // 如果隐式解析可选类型的变量没值,程序一样会崩溃 var intNumber :Int!
//var intNumber1 = intNumber
//print(intNumber1) // 可选绑定
if var intNumber2 = intNumber {
print(intNumber2)
}
二、结构体
Swift的结构体对比OC来说,可以添加初始化方法、可以遵守代理协议等
声明一个结构体的格式:
struct 结构体的名字 {
声明成员变量等
}
计算属性与存储属性
· 存储属性就是类或结构体里定义的变量(或常量)。存储属性可以是变量存储属性(用关键字 var定义),也可以是常量存储属性(用关键字let定义)。
· 除存储属性外,类、结构体和枚举可以定义计算属性。计算属性不直接存储值,而是提供一个必写的getter和一个可选的setter来间接获取和设置其他属性或变量的值。不可以在计算属性中使用self.否则会造成死循环。
// MARK: - 结构体
// 声明一个结构体
struct Rect {
// 声明结构体变量的属性(存储属性)
// 注意,结构体变量中的属性类型可以使用let去修饰,只不过访问的时候不能对其值进行修改
var x : Float
var y : Float
let width : Float
var height : Float
// 声明结构体属性,要使用static
static var description : String?
// 声明一个计算属性(是用来专门计算结构体变量属性的setter方法和getter方法,其本身并没有存储功能)
var centerX : Float {
// setter方法(可以不写setter)
set {
x = newValue // newValue是外界调用方法时传进来的参数
}
// getter方法(必须要写getter)
get {
return x /
}
} var centerY :Float {
get {
return y /
}
} // 声明方法
// 声明结构体变量方法/成员方法(相当于OC中的实例方法)
func frameInfor() {
print("x:\(x), y:\(y), width:\(width), height:\(height)")
}
// 声明结构体方法(相当于OC中的类方法),使用static修饰
static func infor() {
print("这是结构体方法")
}
} // 1、根据结构体去定义一个结构体变量,结构体有自带的构造方法
var frame = Rect(x: , y: , width: , height: )
// 2、访问结构体变量中的属性, 用结构体变量去访问
frame.height =
print(frame.height) // 3、访问结构体属性,用结构体去访问
Rect.description = "是"
print(Rect.description) // 4、访问计算属性
frame.centerX = // 调用了setter方法
print(frame.centerX) // 调用了getter方法 // 5、调用结构体变量方法
frame.frameInfor() // 6、调用结构体方法
Rect.infor()
结构体遵守代理协议(经自己验证,协议中声明的方法只能是计算属性,否则不能遵守)
// 7、结构体遵守代理协议 protocol Named {
var name: String { get }
}
protocol Aged {
var age: Int { get }
}
struct Person: Named, Aged {
var name: String
var age: Int
}
三、类
类是人们构建代码所用的一种通用且灵活的构造体。我们可以使用与结构体完全相同的语法规则来为类定义属性(常量、变量)和添加方法。
我们通过关键字class来定义类,并在一对大括号中定义它们的具体内容:
class ClassName {
类的内部细节
}
声明类方法的方式有两种
使用 static 和 class 都可以修饰类方法,区别在于:class修饰的类方法可以被子类重写;static修饰的类方法不可以被子类重写,防止父类方法被修改
// MARK: - 类(class)
class Person {
// 属性
var name : String?
var age : Int? // 初始化方法
init(name : String, age : Int) {
self.name = name
self.age = age
} // 声明类属性
static var introduce : String? // 声明计算属性(setter,getter, 不能用self. 否则会造成死循环)
var value : Int {
set {
age = newValue // newValue是外界调用方法时从外界传进来的参数
}
get {
return age!
}
} // 声明类方法,在类方法中只能使用类属性,不能使用对象属性
// 1、用static关键字修饰,虽然是一个类方法,但是该方法在子类中不能重写
static func sayHi() {
print(introduce! + "hi")
}
// 2、用class关键字修饰,可以被子类重写
class func sayHello() {
print(introduce! + "hello")
} // 声明实例方法
func sayBey() {
print("BeyBey");
}
} // 1、创建对象,调用初始化方法
var per : Person = Person(name : "MBBoy", age : )
print(per.name! + "\(per.age!)") // 2、访问类属性
Person.introduce = "我是XXX"
print(Person.introduce!) // 3、访问计算属性
per.value = ;
print(per.value) // 4、访问类方法
Person.sayHello()
Person.sayHi() // 5、访问实例方法
per.sayBey() // 定义一个Person类的子类Student,Swift不支持多继承
class Student : Person {
// 重写父类中的类方法
override class func sayHello() {
print("子类Student中重写的类方法sayHello")
} // 重写父类中的实例方法
override func sayBey() {
print("子类Student中重写的实例方法sayBey")
}
} // 1、初始化Student类的对象
var student : Student = Student(name: "yyp", age: )
Student.sayHi() // 2、调用重写的父类中的类方法
Student.sayHello() // 3、调用重写的父类中的实例方法
student.sayBey()
值类型与引用类型
- 值类型:
值类型(Value Types):每个实例都保留了一分独有的数据拷贝,一般以结构体 (struct)、枚举(enum) 或者元组(tuple)的形式出现。
- 引用类型:
引用类型(Reference Type):每个实例共享同一份数据来源(在native层面说的话,就是该类型的每个实例都指向内存中的同一个地址),一般以类(class)的形式出现。
- 值类型与引用类型使用情形
- 使用值类型的情形:
使用==运算符比较实例数据的时候。
你想单独复制一份实例数据的时候。
当在多线程环境下操作数据的时候。 - 使用引用类型(比如class)的情形:
当使用===运算符判断两个对象是否引用同一个对象实例的时候。
当上下文需要创建一个共享的、可变的对象时。
- 使用值类型的情形:
- 值类型与引用类型的区别:
值类型和引用类型最基本的分别在复制之后的结果。- 当一个值类型被复制的时候,相当于创造了一个完全独立的实例,这个实例保有属于自己的独有数据,数据不会受到其他实例的数据变化影响。
- 复制一个引用类型的时候,实际上是默默地创造了一个共享的实例分身,两者是共用一套数据。因此修改其中任何一个实例的数据,也会影响到另外那个。
// MARK: - 值类型和引用值类型
// 值类型
struct animal {
var name : String?
var age : Int? init(name : String, age : Int) {
self.name = name
self.age = age
}
} var dog : animal = animal(name: "阿福", age: )
// 将dog变量的值赋给dog1(其实是一个拷贝的过程)
var dog1 = dog
dog.name = "aFu"
print(dog.name) // 打印结果:aFu
print(dog1.name) // 打印结果:阿福 // 引用值类型
class pet {
var name : String?
var age : Int? init(name : String, age : Int) {
self.name = name
self.age = age
}
} var cat : pet = pet(name: "懵", age: )
// 将cat变量的值赋给cat1(其实是一个引用的过程)
var cat1 = cat
cat.name = "萌"
print(cat.name) // 打印结果:萌
print(cat1.name) // 打印结果:萌
四、协议(protocol)
· 协议定义了一个蓝图,规定了用来实现某一特定工作或者功能所必需的方法和属性
· 类,结构体或枚举类型都可以遵循协议,并提供具体实现来完成协议定义的方法和功能
· 任意能够满足协议要求的类型被称为遵循(conform)这个协议
声明一个带有可选函数的协议时,必须用@objc来修饰,可选函数要用optional关键字修饰
类遵守协议时,直接在本类后面的冒号的后面,使用","号分隔;或者写在父类名后面,使用","号分隔
必须实现的协议方法,就必须实现,否则会报错
直接实现可选协议里的方法,会报警告,可以添加 @objc 或者继承NSObjec
// MARK: - 协议(protocol)
// 在Swift中声明协议的时候,协议里有可选方法时,需要使用@objc关键字修饰 // 结婚协议
@objc protocol MarryProtocol {
func cook() // 做饭
func wash() // 洗衣服
optional func hitDouDou() // 打豆豆,可选方法
} // 离婚协议
protocol DivorceProtocol {
func DivideMoney() // 分财产
} // 继承与Person,实现了MarryProtocol协议和DivorceProtocol协议
// 如果该类是另一个类的子类,先写父类,再写遵循的协议
class Man : Person, MarryProtocol, DivorceProtocol {
@objc func cook() {
print("还好去新东方学了几年的厨艺,终于可以大展身手")
}
@objc func wash() {
print("还好买了台洗衣机")
} func DivideMoney() {
print("分财产")
}
} // 创建一个男人
var man = Man(name: "韦小宝", age: )
man.cook()
man.wash()
man.DivideMoney()
五、扩展(Extension)
· extension + 类名(结构体名字)可以对一个类和结构体扩展方法
· extension可以多次对一个类进行扩展,也可以给一个类扩展协议方法
· 扩展只能增加方法,不能增加属性
// MARK: - 扩展(Extension)
// 1、扩展协议中的相关方法
extension Man {
@objc func hitDouDou() {
print("打豆豆")
}
} man.hitDouDou() // 2、扩展类方法以及对象方法 (类似于OC的类目(Category))
extension Man {
// 对象方法
func sing() {
print("唱歌")
}
// 类方法
class func dance() {
print("growl")
}
} man.sing()
Man.dance()
六、闭包
· 闭包是自包含的函数代码块,可以在代码中被传递和使用。 Swift 中的闭包与 C 和 Objective-C 中的代码块(block)以及其他一些编程语言中的匿名函数比较相似。
· 闭包可以捕获和存储其所在上下文中任意常量和变量的引用。 这就是所谓的闭合并包裹着这些常量和变量,俗称闭包。Swift 会为您管理在捕获过程中涉及到的所有内存操作。
1.语法形式
{(参数)-> 返回值类型 in
执行语句
}
注意:闭包的函数体部分由关键字 in 引入。 该关键字表示闭包的参数和返回值类型定义已经完成,闭包函数体即将开始。
// MARK: - 闭包
// 求两个数的最大值
/*
在OC中使用Block实现
int (^block)(int a, int, b) = ^int (int a, int b) {
return a > b ? a : b;
}
*/ // 使用闭包
var myBlock : ((a : Int, b : Int) -> Int) // 第一种方式
myBlock = {
(a : Int, b : Int) -> Int in
return a > b ? a : b
} // 第二种方式
myBlock = {
(a, b) -> Int in
return a > b ? a : b
} // 第三种方式
myBlock = {
a, b in
return a > b ? a : b
} // 第四种方式
myBlock = {
a, b in
// 不用return关键字
a > b ? a : b
} // 第五种方式
myBlock = {
a, b in
return a > b ? a : b
} let max = myBlock(a: , b: )
print(max)
Swift 基本语法2的更多相关文章
- Swift高级语法学习总结(转)
Swift高级语法学习总结 1.函数 1.1 func funcNmae()->(){} 这样就定义了一个函数,它的参数为空,返回值为空,如果有参数和返回值直接写在两个括号里就可以了 1.2 参 ...
- Swift基础语法学习总结(转)
Swift基础语法学习总结 1.基础 1.1) swift还是使用// 和/* */ 来注释,并且/* */允许多行注释. 1.2) swift使用print和println打印,它的传参是一个泛型 ...
- Swift高级语法学习总结
Swift基础语法学习总结Swift高级语法学习总结Swift语法总结补充(一) 1.函数 1.1 func funcNmae()->(){} 这样就定义了一个函数,它的参数为空,返回值为空,如 ...
- Swift基础语法学习总结
Swift基础语法学习总结Swift高级语法学习总结Swift语法总结补充(一) 1.基础 1.1) swift还是使用// 和/* */ 来注释,并且/* */允许多行注释. 1.2) swift ...
- iOS开发——语法篇&swift经典语法总结
swift经典语法总结 1:函数 1.1 func funcNmae()->(){} 这样就定义了一个函数,它的参数为空,返回值为空,如果有参数和返回值直接写在两个括号里就可以了 1.2 参数需 ...
- swift基本语法
swift种语法着实怪异,实质干的事情还是一样的,一下将对此语法做简单介绍: 1.swift语法种已经剔除“:”这个结束符号,下面将演示入门操作的hello world import Foundati ...
- Swift基础语法
简介 特点 (1)优于OC,快速,安全 (2)取消了预编译指令包括宏定义(OC用的太多了) (3)取消了OC指针和不安全访问的使用(看不到星星了) (4)舍弃 Objective-C 早期应用 Sma ...
- Begin :SWIFT 基本语法
国内介绍IOS书籍大多是很陈旧的代码, 2014年Apple发布了Swift语言, 毫无疑问Swift是一个强大的语言, 但是纵观国内的IOS现状,大家大多已经习惯了了OC, OC能解决的问题谁会想到 ...
- Swift基础语法(三)
Array数组在swift中Array相当于oc中的NSMutableArray(变长数组) //1.定义数组 var numarr:Int[] = [,,,,]; var strarr:String ...
- 【原】iOS学习之Swift之语法2(精简版)
1.可选类型和强制解包(?和!) 1> 可选类型(?)和强制解包(!) 在swift中,可选类型(?) 其根源是一个 枚举型,里面有 None 和 Some 两种类型.其实所谓的 nil 就是 ...
随机推荐
- python set type 集合类型的数据介绍 (set frozenset)
python支持数学中的集合概念,如:通过in,not in 可以检查某元素是否在,不在集合中. python有两种集合类型,set(可以变的,不能哈希,不能用作字典的key),frozenset ...
- HBase Shell输入命令无法删除问题解决技巧
一.引言: HBase shell使用过程中,使用CRT客户端,命令输入后无法删除一直困绕着我,今天终于受不了,几番度娘,谷哥之后,终于有了解决方法,特共享给大家. 二.操作步骤 secureCRT中 ...
- Dreamweaver CS6破解教程[序列号+破解补丁]
Dreamweaver CS6破解教程[序列号+破解补丁] Adobe Dreamweaver CS6中文简体版下载地址:Dreamweaver CS6中文简体版下载[带破解] 破解之前的准备 1 ...
- pku,杨建武:文本挖掘技术
http://webkdd.org/course/ http://www.icst.pku.edu.cn/lcwm/course/WebDataMining/ http://www.icst.pku. ...
- JsonPath详解
JsonPath is to JSON what XPATH is to XML, a simple way to extract parts of a given document. JsonPat ...
- poj 2676 Sudoku ( dfs )
dfs 用的还是不行啊,做题还是得看别人的博客!!! 题目:http://poj.org/problem?id=2676 题意:把一个9行9列的网格,再细分为9个3*3的子网格,要求每行.每列.每个子 ...
- NLog 传递参数
用NLog记文件日志,一般都用{$basedir}变量,把日志记在运行的目录或者它的子目录下,遇到要写在其他目录的下,看了下Nlog找到用环境变量传参数. .net 里写 Environment.Se ...
- [原]Unity3D深入浅出 - 导航网格自动寻路(Navigation Mesh)
NavMesh(导航网格)是3D游戏世界中用于实现动态物体自动寻路的一种技术,将游戏中复杂的结构组织关系简化为带有一定信息的网格,在这些网格的基础上通过一系列的计算来实现自动寻路..导航时,只需要给导 ...
- Visual Studio Developer Command Prompt删除localdb的方法
PM> sqllocaldb.exe stop v11. LocalDB instance "v11.0" stopped. PM> sqllocaldb.exe de ...
- JqueryEasyUI 增加选项卡
function addTab(subtitle,url){ if(!$('#tabs').tabs('exists',subtitle)){ $('#tabs').tabs('add',{ titl ...