可选类型
//
在
swift
中
,
可选类型
?
其根源是一个枚举型
,
里面有
None
和
Some
两种类型
.
其实所谓的
nil
就是
Optional.None,
非
nil
就是
Optional.Some
// 定义一个可选类型 , 表示这个变量可以为 nil
var intNumber : Int ? = 100
// 打印 打印出来是个 Optional 类型的值
print ( intNumber )
// 如果 要取到值 必须对可选类型 强制解包 !
print ( intNumber !)
// 可选类型分为有值和没值 (nil) , 如果可选类型的变量值为 nil( 没值 ) 时对其 强制解包 , 程序会崩溃
// 如果不确定可选类型是否有值时 , 用可选绑定 , 不需要对可选类型解包
if var intNewNumber = intNumber {
print (intNewNumber)
} else {
print ( "error" )
}
// 定义一个可选类型 , 表示这个变量可以为 nil
var intNumber : Int ? = 100
// 打印 打印出来是个 Optional 类型的值
print ( intNumber )
// 如果 要取到值 必须对可选类型 强制解包 !
print ( intNumber !)
// 可选类型分为有值和没值 (nil) , 如果可选类型的变量值为 nil( 没值 ) 时对其 强制解包 , 程序会崩溃
// 如果不确定可选类型是否有值时 , 用可选绑定 , 不需要对可选类型解包
if var intNewNumber = intNumber {
print (intNewNumber)
} else {
print ( "error" )
}
结构体
/*
Swift 的结构体对比 OC 来说 , 可以添加初始化方法 , 可以遵守代理协议等
*/
// 使用 struct 定义一个结构体
// 格式 : struct 结构体名字 { 结构体实现 }
struct Frame {
// 存储属性 : 负责存储值的属性
var x : Float
var y : Float
var width : Float
var height : Float
// 计算属性 : 负责将存储属性进行运算获得的值的属性
//get 方法 : 在属性类型后面添加 {} 使用 get 关键字声明和实现 get 方法
//set 方法 : 同上
var centerX : Float {
//set 方法 不可以单独实现 , 必须搭配着 get 方法
set {
}
//get 方法 可以单独实现
get {
return x + width /2
}
}
var centerY : Float {
get {
return y + height /2
}
}
// 结构体属性
static var myStruct = " 结构体属性 , 只能通过结构体调用 "
// 结构体中可以声明和实现函数
func sayHi() {
print ( " 函数 " )
}
//init 方法
init (x newX : Float , y newY : Float , width newWidth : Float , height newHeight : Float ) {
x = newX
y = newY
width = newWidth
height = newWidth
}
// 结构体的类方法
// 结构体的类方法中只能调用结构体属性
static func sayMy() {
print ( self .myStruct)
}
}
// 属性作用 :
// 声明 _ 实例变量
// 声明和实现 set 方法
// 声明和实现 get 方法
// 结构体调用
Frame . sayMy ()
print ( Frame .myStruct)
// 创建一个对象的方式
// 方式 1: init
var frame1 : Frame = Frame . init (x: 10, y: 10, width: 100, height: 100)
// 方式 2: 自带的构造方法
var frame2 : Frame = Frame (x: 10, y: 10, width: 100, height: 100)
// 对象调用属性
print ( frame1 . centerX )
// 对象调用方法
frame1 . sayHi ()
Swift 的结构体对比 OC 来说 , 可以添加初始化方法 , 可以遵守代理协议等
*/
// 使用 struct 定义一个结构体
// 格式 : struct 结构体名字 { 结构体实现 }
struct Frame {
// 存储属性 : 负责存储值的属性
var x : Float
var y : Float
var width : Float
var height : Float
// 计算属性 : 负责将存储属性进行运算获得的值的属性
//get 方法 : 在属性类型后面添加 {} 使用 get 关键字声明和实现 get 方法
//set 方法 : 同上
var centerX : Float {
//set 方法 不可以单独实现 , 必须搭配着 get 方法
set {
}
//get 方法 可以单独实现
get {
return x + width /2
}
}
var centerY : Float {
get {
return y + height /2
}
}
// 结构体属性
static var myStruct = " 结构体属性 , 只能通过结构体调用 "
// 结构体中可以声明和实现函数
func sayHi() {
print ( " 函数 " )
}
//init 方法
init (x newX : Float , y newY : Float , width newWidth : Float , height newHeight : Float ) {
x = newX
y = newY
width = newWidth
height = newWidth
}
// 结构体的类方法
// 结构体的类方法中只能调用结构体属性
static func sayMy() {
print ( self .myStruct)
}
}
// 属性作用 :
// 声明 _ 实例变量
// 声明和实现 set 方法
// 声明和实现 get 方法
// 结构体调用
Frame . sayMy ()
print ( Frame .myStruct)
// 创建一个对象的方式
// 方式 1: init
var frame1 : Frame = Frame . init (x: 10, y: 10, width: 100, height: 100)
// 方式 2: 自带的构造方法
var frame2 : Frame = Frame (x: 10, y: 10, width: 100, height: 100)
// 对象调用属性
print ( frame1 . centerX )
// 对象调用方法
frame1 . sayHi ()
类 class
/*
类是人么构建代码所用的一种通用且灵活的构造体 . 我们可以使用与结构体完全相同的语法规则来为类定义属性 ( 常量 , 变量 ) 和 添加方法
*/
class Person {
// 类的属性 要设置 初值 或者 可选类型
var name : String = ""
var gender : String ?
var age : Int = 20
// 计算属性
var width : Float {
get {
return 100
}
set {
//set 方法中的 newValue 表示新的值
self . width = newValue
}
}
//static 修饰的是类属性
// 类属性只能由类属性调用
static var hobby : String = "John"
// 普通函数里面不能调用类属性
static func sayWao(){
print ( self .hobby)
}
func sayHello() {
print ( "Hello \ ( self . width )" )
}
init (name newName : String , gender newGender : String , age newAge : Int ) {
name = newName
gender = newGender
age = newAge
}
}
var person : Person = Person . init (name: "Depp" , gender: " 男 " , age: 42)
person . sayHello ()
Person . sayWao ()
// 继承
class Classes {
var student : String = ""
var number : Int ?
//
var sum : Int {
set {
number = newValue
}
get {
return 20
}
}
func read() {
print ( " 早读 " )
}
static var master : String = "A"
static func who() {
print ( self .master)
}
init (student newStudent : String , number newNumber : Int ) {
student = newStudent
number = newNumber
}
}
var classesOne : Classes = Classes . init (student: " 卡特 " , number: 5223)
print ( classesOne . student )
classesOne . read ()
Classes . who ()
// 继承
class student : Person {
var number : Int ?
// 重写父类方法 : 前面需要添加 override 修饰
override func sayHello() {
// super.sayHello()
}
// 重写父类的 init 函数
override init (name newName: String , gender newGender: String , age newAge: Int ) {
super . init (name: newName, gender: newGender, age: newAge)
}
init (number newNumber : Int ) {
super . init (name: "lll" , gender: "nnn" , age: 1)
number = newNumber
}
类是人么构建代码所用的一种通用且灵活的构造体 . 我们可以使用与结构体完全相同的语法规则来为类定义属性 ( 常量 , 变量 ) 和 添加方法
*/
class Person {
// 类的属性 要设置 初值 或者 可选类型
var name : String = ""
var gender : String ?
var age : Int = 20
// 计算属性
var width : Float {
get {
return 100
}
set {
//set 方法中的 newValue 表示新的值
self . width = newValue
}
}
//static 修饰的是类属性
// 类属性只能由类属性调用
static var hobby : String = "John"
// 普通函数里面不能调用类属性
static func sayWao(){
print ( self .hobby)
}
func sayHello() {
print ( "Hello \ ( self . width )" )
}
init (name newName : String , gender newGender : String , age newAge : Int ) {
name = newName
gender = newGender
age = newAge
}
}
var person : Person = Person . init (name: "Depp" , gender: " 男 " , age: 42)
person . sayHello ()
Person . sayWao ()
// 继承
class Classes {
var student : String = ""
var number : Int ?
//
var sum : Int {
set {
number = newValue
}
get {
return 20
}
}
func read() {
print ( " 早读 " )
}
static var master : String = "A"
static func who() {
print ( self .master)
}
init (student newStudent : String , number newNumber : Int ) {
student = newStudent
number = newNumber
}
}
var classesOne : Classes = Classes . init (student: " 卡特 " , number: 5223)
print ( classesOne . student )
classesOne . read ()
Classes . who ()
// 继承
class student : Person {
var number : Int ?
// 重写父类方法 : 前面需要添加 override 修饰
override func sayHello() {
// super.sayHello()
}
// 重写父类的 init 函数
override init (name newName: String , gender newGender: String , age newAge: Int ) {
super . init (name: newName, gender: newGender, age: newAge)
}
init (number newNumber : Int ) {
super . init (name: "lll" , gender: "nnn" , age: 1)
number = newNumber
}
}
协议
/*
协议定义了一个蓝图 , 规定了用来实现某一特定工作 或者 功能所必需的方法和属性
类 , 结构体或枚举类型都可以遵循协议 , 并提供具体实现来完成协议定义的方法和功能
*/
// 声明一个协议
//protocl 声明的协议 是 Swift 的协议 , 所有的方法都必须实现
protocol myDelegata{
// 一个协议方法
func test()
// 使用 mutating 修饰的函数 可以在结构体里面修改结构体的属性
// 协议里面使用 mutating 修饰的函数 , 在遵守协议的时候 可以不使用 mutating 修饰 , 在类里没有影响 , 在结构体力面 , 就不能修改属性的值了 . 但是 如果实现协议里没有 mutating 修饰的函数的时候 , 却用了 mutating 修饰 , 结果是在结构体重新声明了一个函数 , 此函数和协议无关系
mutating func change()
}
// 使用 @objc 修饰的协议 表示 oc 的协议 -> @objc 修饰的协议 不可用在结构体里面遵守
// 使用 @objc 修饰的协议里可以声明可选实现的函数 ( 用 optional 修饰函数 )
// 在实现这个函数的时候 , 在函数前面要加 @objc 修饰
@objc protocol newDelegate{
optional func newTest()
func newChange()
}
//
class Teacher: Person , myDelegata , newDelegate {
func test() {
print ( "233333" )
}
// 协议里使用 mutating 修饰的函数 , 在类里面就是一个普通的函数
func change() {
}
// 协议里 optional 修饰的可以选择实现
// @objc func newTest(){
// }
@objc func newChange() {
}
}
let teacher : Teacher = Teacher (name: "a" , gender: "b" , age: 233)
teacher . test ()
struct myStruct: myDelegata {
var name : Int ?
func test() {
print ( "3444444" )
}
mutating func change() {
name = 100
}
}
协议定义了一个蓝图 , 规定了用来实现某一特定工作 或者 功能所必需的方法和属性
类 , 结构体或枚举类型都可以遵循协议 , 并提供具体实现来完成协议定义的方法和功能
*/
// 声明一个协议
//protocl 声明的协议 是 Swift 的协议 , 所有的方法都必须实现
protocol myDelegata{
// 一个协议方法
func test()
// 使用 mutating 修饰的函数 可以在结构体里面修改结构体的属性
// 协议里面使用 mutating 修饰的函数 , 在遵守协议的时候 可以不使用 mutating 修饰 , 在类里没有影响 , 在结构体力面 , 就不能修改属性的值了 . 但是 如果实现协议里没有 mutating 修饰的函数的时候 , 却用了 mutating 修饰 , 结果是在结构体重新声明了一个函数 , 此函数和协议无关系
mutating func change()
}
// 使用 @objc 修饰的协议 表示 oc 的协议 -> @objc 修饰的协议 不可用在结构体里面遵守
// 使用 @objc 修饰的协议里可以声明可选实现的函数 ( 用 optional 修饰函数 )
// 在实现这个函数的时候 , 在函数前面要加 @objc 修饰
@objc protocol newDelegate{
optional func newTest()
func newChange()
}
//
class Teacher: Person , myDelegata , newDelegate {
func test() {
print ( "233333" )
}
// 协议里使用 mutating 修饰的函数 , 在类里面就是一个普通的函数
func change() {
}
// 协议里 optional 修饰的可以选择实现
// @objc func newTest(){
// }
@objc func newChange() {
}
}
let teacher : Teacher = Teacher (name: "a" , gender: "b" , age: 233)
teacher . test ()
struct myStruct: myDelegata {
var name : Int ?
func test() {
print ( "3444444" )
}
mutating func change() {
name = 100
}
}
扩展 extension
/*
extension + 类名 表示要给这个类做扩展
extension 只可以扩展函数 , 不能扩展属性
extension 可以给一个类扩展代理协议
*/
extension Person : myDelegata {
func test() {
}
func change() {
}
func sayNoNoNo(){
}
}
// extension 可以给结构体扩展新的协议
extension Frame : myDelegata {
func test() {
}
func change() {
}
}
extension + 类名 表示要给这个类做扩展
extension 只可以扩展函数 , 不能扩展属性
extension 可以给一个类扩展代理协议
*/
extension Person : myDelegata {
func test() {
}
func change() {
}
func sayNoNoNo(){
}
}
// extension 可以给结构体扩展新的协议
extension Frame : myDelegata {
func test() {
}
func change() {
}
}
闭包
/*
闭包是自包含的函数代码块 , 可以在代码中被传递和使用 .
Swift 中的闭包与 C 和 OC 中的代码块 block 以及其他一些编程语言中的 匿名函数比较相似
闭包可以捕获和存储其所在上下文中任意常量和变量的引用 . 这就是所谓的闭合并包裹着这些常量和变量 , 俗称闭包 .Swift 会为管理捕获过程中的内存操作
*/
var myBlock : ((a : Int , b : Int ) -> Int )
// 1
myBlock = {
(a : Int , b : Int ) -> Int in
return a > b ? a : b
}
// 2 省略参数和返回值类型
myBlock = {
a, b in
return a > b ? a : b
}
// 3 省略参数和返回值类型 , 省略 return 关键字
myBlock = {
a, b in
a > b ? a : b
}
// 4 使用 $ 符号表示 取第几个参数
myBlock = {
$0 > $1 ? $0 : $1
}
// 5 官方推荐的格式
myBlock = {
(a, b) -> Int in
return a > b ? a : b
}
值类型与引用类型
值类型:
该类型的每个实例持有数据的副本, 并且该副本对于每个实例来说是对无二的一份, 比如结构体(struct), 枚举(enum), 元组(tuple)都是值类型
引用类型:
该类型的实例共享数据唯一的一份副本 (在native层面说的话, 就是该类型的每个实例都指向内存中的同一个地址), 比如(类)就是引用类型.
使用值类型的情形:
使用==运算符比较实例数据的时候;
想单独复制一份实例数据的时候
当在多线程环境下操作数据的时候.
使用引用类型(比如class)的情况:
当使用==运算符判断两个对象是否引用同一个对象实例的时候.
当上下文需要创建一个共享, 可变的对象时.
/*
存储属性就是类 或 结构体定义的变量 ( 或 常量 ). 存储属性可以是变量存储属性 ( 用关键字 var 定义 ), 也可以是常量存储属性 ( 用关键字 let 定义 )
除存储属性外 , 类 , 结构体和枚举 可以定义计算属性 . 计算属性不直接存储值 , 而是提供一个 getter 和 一个可选 的 setter, 来间接获取和设置其他属性或变量的值
存储属性就是类 或 结构体定义的变量 ( 或 常量 ). 存储属性可以是变量存储属性 ( 用关键字 var 定义 ), 也可以是常量存储属性 ( 用关键字 let 定义 )
除存储属性外 , 类 , 结构体和枚举 可以定义计算属性 . 计算属性不直接存储值 , 而是提供一个 getter 和 一个可选 的 setter, 来间接获取和设置其他属性或变量的值
*/