- 在Mac终端输入
swift
可查看当前系统所支持的Swift语言的版本,如下所示:
- 在Mac终端输入
xcrun swift -version
,可查看Xcode版本对应的Swift版本,如下所示:
- 在Mac终端输入
xcodebuild -showsdks
,可查看Xcode所支持的系统版本,如下所示:
Swift初次体验
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let a = 100; let b = 200
print(a+b)
let view1 = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view1.backgroundColor = UIColor.red
view.addSubview(view1)
let button = UIButton(type: UIButton.ButtonType.contactAdd)
button.center = view.center
button.addTarget(self, action: #selector(click(button:)), for: UIControl.Event.touchUpInside)
view.addSubview(button)
}
//按钮的监听回调
@objc func click(button: UIButton){
print("点击")
}
}
- 在Swift中,一段代码之后不需要分号,在OC中需要;
- 在Swift中,若多个语句并列,之间要加分号;例如
let a = 100; let b = 200
- 在Swift中,
() 代表构造函数
,创建并初始化对象,相当于OC中 alloc init
;
- 在Swift中,写括号时,
先只写一个左括号,会有代码提示
;
- 在Swift中,获取系统颜色:
UIColor.red
相当于OC中[UIColor redColor];
- 在Swift中,
可以省略 self. 也可以加上,个人建议不要加上
,在闭包中必须加上 self.
- 在Swift中,print函数相当于OC中NSLog函数,其执行效率更高;
- 在Swift中,按钮添加监听方法,
#selector(方法名())
,如果有参数需添加冒号 #selector(方法名(参数:))
常量与变量
- 常量,一旦定义初始化了,就不能再修改,用关键字
let
修饰,否则会报错Immutable value 'x' may only be initialized once
;
- 常量的值不要求在编译期确定,但
使用之前必须赋值一次
;
- 变量,定义初始化了,可以多次修改,用关键字
var
修饰;
-
常量与变量在初始化之前,是不能使用的,如果使用会报错
;
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//定义常量
let x = 20
//x = 80
//定义变量
var y = 40
y = 50
print(x+y)
//view1初始化
let view1 = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
view1.backgroundColor = UIColor.green
view.addSubview(view1)
}
}
- 控件view1初始化之后用let修饰,后面修改了其属性,并没有修改指针的地址,即view1始终指向UIView的实例对象,所以可以用常量let修饰;
类型的自动推导
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let x = 20
let y = 3.5
let r1 = x + Int(y)
let r2 = Double(x) + y
let r3 = x + y
}
}
- 发现 let r3 = x + y这行代码报错;
-
按住option键,再左点击x
,发现常量x的类型为Int,我们并没有声明常量x的类型,但它的类型已经被确定为Int整型,是因为Swift语言的中自动推导,会根据设置数值的右侧代码,推断出常量/变量的数据类型
;
-
在Swift中任何两个不同类型的变量或者常量,是不允许直接计算
,这就是为什么let r3 = x + y报错的原因,要想计算必须进行数值类型的转换,转成同一种类型,才能进行计算;
- let r3 = x + y这行代码报错也证明:
在Swift中,在任何时候,变量或者常量都不会做隐式转换
;
- Swift是一个对
数据类型要求异常严格
的语言;
- Int --> 64位整数 相当于OC中 long;
- Double --> 双精度的小数,相当于OC中 CGFloat;
初识可选项Optional
- 可选项:表示一个变量可以为
本身类型
,也可以为nil
;
- 定义一个常量或者变量,如果需要指定其类型,可使用
常量/变量 : 类型
的方式指定其准确的类型;
- 可选项 使用
?
进行定义;
- 可选项Optional可视为一种数据类型;
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let x : Double = 20
print(x)
var y : Int?
print(y)
y = 30
print(y)
}
}
- let x : Double = 20:指定了常量x的类型为Double;
- var y : Int? :定义变量y为可选项类型,那么变量y可以是一个整数,也可以是nil,在
未初始化时默认情况下是nil
;
- y = 30:对变量y进行赋值,可选项在输出的时候,会提示
Optional
,调试结果如下:
- 使用可选项的变量,
其值可能有两种类型,一种是本身类型,另一种是nil
,所以在Swift中可选项是不能直接参与运算的
;
-
!
感叹号 --> 在Swift中表示强行解包(unwrapping)
,进行解包操作时一定要保证可选项变量有值,才能解包成功,否则就会出现崩溃
;
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var x : Int?
x = 30
print(x!+20)
}
}
- var x : Int?:x为可选项,然后初始化为30;
- x! 强制解包,获取x的值,然后参与运算;
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var x : Int?
}
}
- var x : Int? :定义了一个可选项变量x,出现警告
Variable 'x' was never used; consider replacing with '_' or removing it
,是说x没有被使用,建议直接移除,现做如下修改:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var x : Int?
x = 30
}
}
- 可选项变量x 对其初始化为30,依然出现警告
Variable 'x' was written to, but never read
表示 x 只做了写的操作,没有进行读取操作,再作修改如下:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var x : Int?
x = 30
print(x)
}
}
- 可选项变量x 定义且初始化后,再读取打印其值,还是出现警告
Expression implicitly coerced from 'Int?' to 'Any'
解决方案:在使用x值的时候使用强制解包
,修改如下:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var x : Int?
x = 30
print(x!)
}
}
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var x : Int?
print(x!)
}
}
- 运行直接崩溃,报错
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
- 上面已经提到可选项变量
强行解包(unwrapping)
表明可选项修饰的变量一定有值,如果没有,就会出现崩溃,这里的x没有初始化其值默认为nil,所以出现崩溃;
- 所以可选项变量在使用!强行解包的时候,要确保变量一定有值,下面来看一段代码:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let x : Int?
if x != nil {
print(x!)
}
}
}
- if x != nil 执行会报错,提示
Constant 'x' used before being initialized
,表明可选项常量x在使用之前必须要初始化,否则会报错
;
- 若将let 改成var,就不会报错了,这是因为
可选项变量在定义的时候若没有初始化,会默认初始化为nil
;
总结:
-
var的可选项默认值是nil
;
-
let的可选项是没有默认值的,必须要初始化值,否则访问会报错
;
- 无论var还是let,在使用之前必须初始化,否则直接使用就会崩溃;
?? 操作符
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var x : String?
x = "liyanyan"
if x != nil {
print(x! + "好")
}
print((x ?? "空的") + "也好")
}
}
-
??
操作符:表示判断变量是否为nil,若为nil,则使用后面的字符进行替换;
- 上面代码的执行结果为:
liyanyan好 liyanyan也好
;
- 若将
x = "liyanyan"
移除,执行结果为空的也好
;
标识符
- 标识符(比如常量名,变量名,函数名)几乎可以使用任何字符;
- 标识符不能以数字开头,不能包含空白字符,制表符,箭头等特殊字符;
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//: # 一级标题
🙂()
let 😎 = "hehe"
print(😎)
var 😍 = "like"
print(😍)
}
func 🙂() {
print("haha")
}
}
常见的数据类型
字面量
- 布尔:let bool = true
- 字符串:let str = "liyanyan"
- 字符:let char : Character = "1";必须指明其类型位 为Character,否则默认为字符串;
- 整数:
- 十进制:let a = 17
- 二进制:let b = 0b0001
- 八进制:let c = 0o21
- 十六进制:let d = 0x11
- 浮点数:
- 十进制:let a = 125.0,等价于1.25e2;
- 十六进制 let b = 0xFp2,等价于15*2^2 = 60.0;p是特殊字符表示幂运算;
- 十六进制 let b = 0xFp-2,等价于15*2^-2 = 3.75;F是十六进制等于15;
- 整数和浮点数可以添加额外的零或者下划线来增强可读性;
- 100_0000 :表示100万
- 数组:let arr = [1,2,3]
- 字典:let dic = ["age":13,"name":"liyanyan"]
类型转换
let int1:UInt16 = 2_000
let int2:UInt8 = 1
//将int2 -- 转成UInt16 同种类型才能运算
let int3 = int1 + UInt16(int2)
let int = 10
let double = 0.1234
let p = Double(int) + double
- 字面量是可以直接运算的,因为字面量本身没有明确的类型
let result = 3 + 0.1234
元组(tuple)
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let error = (404,"Not Found")
print(error.0)
print(error.1)
let (statuCode,StatuMsg) = error
print(statuCode)
let (statuCode1,_) = error
print(statuCode1)
let error1 = (statuCode:200,desc:"OK")
print(error1.statuCode)
print(error1.desc)
}
}
-
let error = (404,"Not Found")
:是一个元组,内部包含两种数据类型,整型与字符串,内部元素可通过下标进行访问;
-
let (statuCode,StatuMsg) = error
:元组之间可以赋值
-
let (statuCode1,_) = error
:元组之间可以赋值,对于不需要的数据项可以使用_
进行忽略;
-
let error1 = (statuCode:200,desc:"OK")
:元组内部元素的前面可添加参数,以后访问可以通过参数进行访问;
关于自增运算