swift基本语法
Posted 萧家大公子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swift基本语法相关的知识,希望对你有一定的参考价值。
一 可选类型知识点补充
1 例一 : 强转并且制定类型
let str = "23" //打印结果: "23"
let age : Int? = Int(str) //打印结果 :23
—-> 1.1 问题 : 该例子转化的结果为什么需要用可选类型来接收?
—-> 1.2 解答 : 因为很有可能是转化不成功的,如果此时不用可选类型来接收的话,万一转化失败,那么该值就为空(nil),如果不选择可选类型来接收,程序会崩溃.
2 例二 : 获取某个plist文件的路径
let path : String? = NSBundle.mainBundle().pathForResource("xiaofeng.plist", ofType: nil) //打印的结果为nil,因为写程序的时候并没有新建一个名字为"xiaofeng"的plist文件
if let path = path
NSArray(contentsOfFile: path)
—-> 2.1 这里同样需要用可选类型来接收,原因是很有可能找不到名字为”xiaofeng”的plist文件,如果此时不用可选类型来接收,值为nil,程序会崩溃.
—-> 2.2 在此句后面写一个判断语句更加安全的判断是否可以取成功.判断的好处如下:
—> 2.2.1 判断path是否有值,如果没有值的话,就不执行中的内容
—> 2.2.2 如果path有值,那么系统就会对path进行解包,并且将解包的结果赋值
3 例三 : 获取一个NSURL
let url : NSURL? = NSURL(string: "www.baidu.com") //打印结果:www.baidu.com
if let url = url
NSURLRequest(URL : url) //<NSURLRequest: 0x7fd050d18610> URL: www.baidu.com
—-> 3.1 如果不加判断或者将获取到的值不用可选类型来接收的话,那么当url是下面这种类型,就获取不到.不用选类型来接收是会报错的.
//url中出现了中文,并且没有用可选类型来接收值,系统会报错
//系统包的错误: cannot convert value of type 'NSURL?' to specified type 'String'
let url : String = NSURL(string: "www.baidu.com/百度")
—-> 3.2 如果用if做出了判断,此时能更加安全的对url进行操作,判断url是否获取成功,成功的话就将url解包.
4 例三 : 在保证一个可选类型一定有值的前提下,可以直接强制解包
—-> 4.1 如果此时的123.plist文件存在的话,就可以强制解包(通过按住option点击path1可以看出,path1的类型是可选类型)
let path1 = NSBundle.mainBundle().pathForResource("123.plist", ofType: nil)
二 is; as?; as!的用法
1 is : 用来判断某种类型是不是另外一种类型(用法比较简单)
let array = [12,"xiaofeng",1.89]
let arrayM = [NSObject]()//定义数组,内部的元素是NSObject类型
//判断取出的第一个元素是不是整型
if let firstObject = array.first
if firstObject is Int
print("是Int类型") //打印结果:"是Int类型\\n"
else
print("不是Int类型")
2 as? : 转成的最终类型是一个可选类型(需要作出判断)
let dict = ["name" : "xiaofeng", "age" : 20, "height" : 1.88]
let value = dict["name"] //通过按住option点击value,可以看出类型为可选类型
//将NSObject转成String类型
if let value = value
//此处value as? String也有可能转失败
let valueStr : String? = value as? String
//判断是否能转成功
if let valueStr = valueStr
let info = "my name is " + valueStr //最终结果:"my name is xiaofeng"
—-> 2.1 简便写法判断NSObject? 转 String
if let valueStr = value as? String
let info = "my name is " + valueStr //打印结果 :"my name is xiaofeng"
3 as! : 转成的最终类型就是具体的类型(NSObject? 转成 String)
—-> 3.1 此方法的后果: 如果用这种方法转化不成功,那么程序会直接崩溃
let info = "my name is " + (value as! String) //打印结果 :"my name is xiaofeng"
三 swift中的函数
1 oc中的方法
有参数有返回值
- (CGFloat)sum:(CGFloat)num1 num2:(CGFloat)num2;
有参数没有返回值
- (void)sum1:(CGFloat)num1 num2:(CGFloat)num2;
没有参数有返回值
- (CGFloat)sum2;
没有参数没有返回值
- (void)sum3;
2 swift中的函数相当于oc中的方法(格式如下)
func 函数名(参数列表) -> 返回值类型
代码块
return 返回值
—-> 2.1 func是关键字,多个参数列表之间可以用逗号(,)分隔,也可以没有参数
—-> 2.2 使用箭头“->”指向返回值类型
—-> 2.3 如果函数没有返回值,返回值为Void.并且“-> 返回值类型”部分可以省略
3 常见的函数类型
—-> 3.1 有参数有返回值
func sum (num1 : Int , num2 : Int) ->Int
return num1 + num2
let result = sum(10, num2: 10)
print("计算的结果是:\\(result)") //打印结果 : "计算的结果是:20\\n"
—-> 3.2 有参数没有返回值
func minus (num1 : Double , num2 : Double)
print(num1 - num2) //打印出来的结果 : "2.0\\n"
minus(22.1, num2: 20.1)
—-> 3.3 没有参数有返回值
func multiply() ->Int
return 10 //返回结果 : 10
multiply()
—-> 3.4 没有参数没有返回值
func divide()
divide()
—-> 3.5 有参数有多个返回值(元组)
—-3.5.1 计算一个数组中奇数和偶数的个数?
* 普通写法:
let array = [11,22,44,33,66,88]
var oddCount = 0 //奇数
var evenCount = 0 //偶数
for num in array
if num % 2 == 0
evenCount++ //打印结果 : 4
else
oddCount++ //打印结果 : 2
* 利用元组特性作为多个返回值
let nums = [11,22,33,44,55,7,77,88]
func getCount (nums : [Int]) ->(Int,Int)
var evenCount = 0 //偶数
var oddCount = 0 //奇数
for num in nums
if num % 2 == 0
evenCount++ //打印结果 : 3
else
oddCount++ //打印结果 : 5
return (evenCount,oddCount)
let count = getCount(nums)
print("偶数的个数是:\\(count.0),奇数的个数是:\\(count.1)")
4 内部参数和外部参数
—-> 4.1 含义: 内部参数: 在函数内部可以看到的参数,就是内部参数;外部参数: 在函数外面可以看到的参数,就是外部参数
func sum (num1 : Int , num2 : Int , num3 : Int) ->Int
print(num1)
print(num2)
print(num3)
return num1 + num2 + num3 //返回结果 : 30
//调用
sum(10, num2: 10, num3: 10)
—-> 4.2 为什么上面代码在调用的时候,num1并没有显示出来,而是从num2开始显示的?
—-> 4.3 解答 : 默认情况下,从第二个参数开始,参数名称既是内部参数也是外部参数
—-> 4.4 如何让第一个参数也是外部参数?
—-> 4.5 解答 : 可以在第一个标识符前加上和该标识符同名的标识符
func multiply (num1 num1 : Int , num2 : Int , num3 : Int) ->Int
return num1 * num2 * num3 //返回结果 : 1000
multiply(num1: 10, num2: 10, num3: 10)
—-> 4.6 如何让外部参数不显示?
—-> 4.7 可以在参数名称前加下划线(_)
func subtraction (num1 : Int , _ num2 : Int , _ num3 : Int) ->Int
return num1 - num2 - num3 //返回结果 : 50
subtraction(100, 20, 30)
5 默认参数
—-> 5.1 含义 : 某些情况,如果没有传入具体的参数,可以使用默认参数(“蓝山”)
—-> 5.2 需求 : 刚进入公司作为新员工,老员工需要你帮他们泡咖啡,他们说了各自的咖啡需求,但是有一些人没有说,只说了随便,此时要你设计一个函数求出咖啡的种类?
func makeCoffee(coffeeName : String = "蓝山") ->String
return "制作了一杯:\\(coffeeName)咖啡"
makeCoffee("拿铁") //通过传入咖啡的名称,返回制作好的咖啡
makeCoffee() //此时的调用函数,返回的结果是默认设置的"蓝山"咖啡
6 可变参数
—-> 6.1 含义与条件
—–> 6.1.1 swift中函数的参数个数可以变化,它可以接受不确定数量的输入类型参数
—–> 6.1.2 它们必须具有相同的类型
—–> 6.1.3 我们可以通过在参数类型名后面加入(…)的方式来指示这是可变参数
—-> 6.2 需求 : 第一天 老板要你通过函数计算两个数的相加;第二天 老板要你通过函数计算三个数的相加; 第三天 老板要你通过函数计算四个数的相加
//此时需要些三个方法来计算
func sum(num1 : Int , num2 : Int) ->Int
return num1 + num2
func sum(num1 : Int , num2 : Int , num3 : Int) ->Int
return num1 + num2 + num3
func sum(num1 : Int , num2 : Int , num3 : Int , num4 : Int) ->Int
return num1 + num2 + num3 + num4
sum(10, num2: 20, num3: 30, num4: 40)
—-> 6.3 使用可变参数进行改进
//计算参数为数组中的各个元素的和(方法一)
func arrayCount(nums : [Int]) ->Int
var result = 0
for num in nums
result += num
return result
arrayCount([10,20,30,40]) //传入一个数组 打印结果是 : 100
//计算参数为数组中的各个元素的和(方法二)
func sunNums(nums : Int...) ->Int
var result = 0
for num in nums
result += num
return result
sunNums(10,20,30,40)
7 引用类型(指针的传递)
—-> 7.1 默认情况下,函数的参数是值传递.如果想改变外面的变量,则需要传递变量的地址
—-> 7.2 必须是变量,因为需要在内部改变其值
—-> 7.3 Swift提供的inout关键字就可以实现
—-> 7.4 需求 : 用函数交换两个数的值
—–> 7.4.1 错误写法 :
var m = 20
var n = 30
func exchangeNum(var num1 : Int , var num2 : Int)
let tempNum = num1
num1 = num2
num2 = tempNum
exchangeNum(m, num2: n)
print("m :\\(m), n: \\(n)") //打印出结果 : "m :20, n: 30\\n"
—–> 7.4.2 正确写法 一: 运用指针进行交换(swift提供的关键字: inout)
var a = 20
var b = 30
func exchangeNum(inout num1 : Int , inout num2 : Int)
let tempNum = num1
num1 = num2
num2 = tempNum
exchangeNum(&a, num2: &b)
print("a : \\(a) , b : \\(b)") //打印结果 : "a : 30 , b : 20\\n"
—–> 7.4.3 特别写法 :
var c = 20
var d = 30
func exchangeNum( num1 : Int , num2 : Int) -> (Int , Int)
return (num2 ,num1)
let num = exchangeNum(c, num2: d)
c = num.0 //打印结果 : 30
d = num.1 //打印结果 : 20
8 函数的嵌套使用
—-> 8.1 在swift中函数是可以嵌套使用的(不推荐)
func test()
func demo()
print("demo")
demo() //先打印:demo
print("test") //再打印:test
// demo() //如果在此处调用 先打印:test 再打印:demo
test()
9 函数的类型
—-> 9.1 定义两个函数
func add(a : Int , b : Int) ->Int
return a + b
func mul(a : Int , b : Int) ->Int
return a * b
—-> 9.2 写出函数的类型 (函数相当于一个值)
var a = add //打印出函数的类型 : (Int, Int) -> Int
var a : (Int, Int) -> Int = add
a(20,30) //打印结果 : 50
a = mul //打印结果 : (Int, Int) -> Int
a(30,60) //打印结果 : 1800
—-> 9.3 函数作为方法的参数
—–> 9.3.1 定义一个函数
var m : Int = 20
func test(num : Int) ->Int
return num
test(m) //打印结果 : 20
test(30) //打印结果 : 30
—–> 9.3.2 用第一个函数作为第二个函数的参数
func demo(funcName : (Int) ->Int)
funcName(20)
demo(test)
—–> 9.3.3 函数作为方法的返回值
func add(a : Int , b : Int) ->Int
return a + b
func demo1() ->((Int, Int) ->Int) //返回值的类型必须是和返回函数同种类型
return add
let tempFunc = demo1()
tempFunc(20,30)
四 枚举
1 OC中的枚举 : 指定相关名称为一组整型值
typedef enum
SexMan, //默认为0
SexWoMan //1
Sex
2 swift中的枚举 : Swift 中的枚举更加灵活,不必给每一个枚举成员提供一个值.也可以提供一个值是字符串,一个字符,或是一个整型值或浮点值.
3 swift枚举的语法
enum SomeEnumeration
// 属性(enumeration definition goes here)
4 定义swift中的枚举(并没有规定Man,WoMan的数值)
//单个值一行
enum Sex
case Man
case WoMan
//多个值一行
enum Direction
case East,West,South,North
5 创建枚举具体类型
var sex = Sex.Man
sex = .WoMan
6 给枚举类型赋具体值
enum Planet : Int
case Mercury = 0, venus, Earth, Mars
enum Sex1 : Int
case Man = 0
case WoMan = 1
enum Sex2 : String
case Man = "男"
case WoMan = "女"
7 通过下面的方法来取出枚举中的属性(rawValue:)
let sex1 = Sex1(rawValue: 0) //打印出结果 : Man
let sex2 = Sex1(rawValue: 1) //打印出结果 : WoMan
let sex4 = Sex2(rawValue: "男") //打印出结果 : Man
let sex5 = Sex2(rawValue: "女") //打印出结果 : WoMan
五 结构体
1 结构体的具体使用
—-> 1.1 需求 : 判断两个点之间的距离是否大于某个数字?
—-> 1.2 传统做法
//1.定义中心点
let centerX : Double = 100
let centerY : Double = 100
//获取比较的点
let x : Double = 60
let y : Double = 50
let x1 : Double = 200
let y1 : Double = 150
//定义方法,用来比较两个点
func inRange(x : Double, y : Double) ->Bool
//获取两个点之间的距离
let disX = x - centerX
let disY = y - centerY
//计算第三边的距离
//pow(disX, 2)代表了disX的2次方;sqrt代表开方根
let distance = sqrt(pow(disX, 2) + pow(disY, 2))
//判断是否小于200
return distance < 200 //打印结果 : true
inRange(60, y: 50)
—-> 1.3 使用结构体进行该进(优点) : 看上去比较直观,一眼就知道代表了点
//结构体定义
struct Location
var x : Double
var y : Double
//通过结构体创建对应的点
let center = Location(x: 100, y: 100)
//需要判断的点
let testLocation = Location(x: 50, y: 40)
//定义函数
func inRang(location : Location) ->Bool
let disX = location.x - center.x
let disY = location.y - center.y
let distance = sqrt(pow(disX, 2) + pow(disY, 2))
return distance < 200
//方法的调用
inRang(testLocation)
2 结构体扩充构造函数
—-> 2.1 swift规范 : 在实例化任何一个类或者结构体时,必须保证类/结构体所有(存储)属性,都必须被初始化.
—-> 2.2 如果自定义了构造函数,那么会覆盖系统提供的构造函数.如果希望保留原来的构造函数,那么必须明确的将系统提供的构造函数进行重写
struct Location
var x : Double = 0
var y : Double = 0
var z : Double = 0
//init()是系统的构造方法
init()
//自定义构造方法
init(x : Double, y : Double, z : Double)
self.x = x
self.y = y
self.z = z
—-> 2.3 注意一 :如果没有自定义构造方法,是可以敲出下面的方法来
Location()
—-> 2.4 注意二 : 自定义了构造方法,同时重写了系统的构造方法是可以同时敲出下面的方法
Location() //如果init()构造方法没有被重写,是无法敲出来的
//创建Location实例
let location = Location(x: 100, y: 100, z: 100)
—-> 2.5 注意三 : 系统的结构体除了可以通过make方法创建外,也可以直接结构体名称后面跟上()来创建
let point = CGPoint(x: 100, y: 100)
let size = CGSize(width: 100, height: 100)
let rect = CGRect(origin: point, size: size)
var rect1 = CGRect().origin.x
rect1 = 100
let rect2 = CGRect(x: 0, y: 0, width: 100, height: 100)
let range = NSRange(location: 3, length: 9)
3 结构体扩充函数
—-> 3.1 给结构体扩充方法,必须在func前加上Mutating
—-> 3.2 给自定义的结构体扩充函数
struct Location
var x : Double
var y : Double
//mutating少了是会报错的
mutating func moveH(dis : Double)
x += dis
mutating func moveV(dis : Double)
y += dis
var location = Location(x: 50, y: 60)
location.moveH(-100)
location.moveV(100)
print(location) //打印出结果 : "Location(x: -50.0, y: 160.0)\\n"
—-> 3.3 给系统的结构体扩充方法
extension CGPoint
mutating func moveH(dis : CGFloat)
x += dis
mutating func moveV(dis : CGFloat)
y += dis
var point = CGPoint(x: 100, y: 100)
point.moveH(100)
print(point) //打印出结果 : "(200.0, 100.0)\\n"
—-> 3.4 给系统的类扩充方法(必须使用系统给的关键字:extension)
extension UIButton
func getTitle() ->String?
return titleLabel?.text
let btn = UIButton()
btn.setTitle("按钮", forState: .Normal)
print(btn.getTitle()) //打印出结果 : "Optional("按钮")\\n"
六 类
1 定义类
—-> 1.1 类的定义
class 类名 : SuperClass
// 定义属性和方法
—-> 1.2 注意 : (1)定义的类,可以没有父类.那么该类是rootClass (2)通常情况下,定义类时.继承自NSObject(非OC的NSObject)
2 类的属性
—-> 2.1 类的属性种类
—–> 2.1.1 存储属性:存储实例的常量和变量
—–> 2.1.2 计算属性:通过某种方式计算出来的属性
—–> 2.1.3 类属性:与整个类自身相关的属性
3 存储属性
class Person: NSObject
var name = ""
var age = 0
var mathScore = 0.0
var chineseScroe = 0.0
//创建Person对象
let p = Person()
//给存储属性赋值
p.name = "xiaofeng"
p.age = 19
p.mathScore = 90
p.chineseScroe = 100
4 计算属性(本质是一个方法)
1> 计算属性并不存储实际的值,而是提供一个getter和一个可选的setter来间接获取和设置其它属性
2> 计算属性一般只提供getter方法
3> 如果只提供getter,而不提供setter,则该计算属性为只读属性,并且可以省略get
—-> 4.1 需求:计算一个学生的两门课程的平均成绩
class Person: NSObject
var name = ""
var age = 0
var mathScore = 0.0
var chineseScroe = 0.0
//计算属性(本质是一个方法)
func getAverageScore() ->Double
return (mathScore + chineseScroe) * 0.5
//创建Person对象
let p = Person()
//给存储属性赋值
p.name = "xiaofeng"
p.age = 19
p.mathScore = 90
p.chineseScroe = 100;
//调用方法
print(p.getAverageScore()) //打印结果 : "95.0\\n"
—-> 4.2 计算属性的完整写法
var averageScore : Double
get
return (mathScore + chineseScroe) * 0.5
set (newScore)
chineseScroe = 2 * newScore - mathScore
—-> 4.3 计算属性常见写法
var averageScore : Double
return (mathScore + chineseScroe) * 0.5
5 类属性
—-> 5.1 类属性是与类相关联的,而不是与类的实例相关联
—-> 5.2 所有的类和实例都共有一份类属性.因此在某一处修改之后,该类属性就会被修改
—-> 5.3 类属性的设置和修改,需要通过类来完成
static var courseCount = 0
//设置课程个数
Person.courseCount = 3
//取出类属性的是
print(Person.courseCount)
6 类的构造函数
—-> 6.1 默认情况下,系统会给类提供一个最简单的构造函数 init()
—-> 6.2 创建出来一个对象,必须保证该对象内部所有的属性都有初始化值
—-> 6.3 如果自定义构造函数init(),会覆盖系统默认提供的init()构造函数,如果不希望覆盖,那么必须明确的实现init()构造函数
class Person
var name : String = ""
var age : Int = 0
//系统的构造函数
init()
//添加构造函数
init(name : String, age : Int)
self.name = name
self.age = age
//用字典添加
init(dict : [String : NSObject])
if let name = dict["name"] as? String
self.name = name
if let age = dict["age"] as? Int
self.age = age
—-> 6.4 创建对象
//2.创建类对象
let p = Person()//通过普通方法创建
//通过扩充的方法创建
let p1 = Person(dict: ["name" : "xiaofeng", "age" : 19])
7 类的字典转模型(KVC)
—-> 7.1 利用KVC字典转模型会更加方便
—-> 7.2 注意:
—–> 7.2.1 KVC并不能保证会给所有的属性赋值
—–> 7.2.2 因此属性需要有默认值
class Person : NSObject
var name : String = ""
var age : Int = 0
init(dict :[String : NSObject])
//必须先初始化对象
super.init()
setValuesForKeysWithDictionary(dict)
//如果使用KVC的时候,发现模型属性值并不能一一对应,此时使用kvc是会报错的,但是重写下面这个方法可以避免系统报错
override func setValue(value: AnyObject?, forUndefinedKey key: String)
let p = Person(dict: ["name" : "xiaofeng", "age" : 18])
print(p.name) //打印结果 : "xiaofeng\\n"
print(p.age) //打印结果 : "18\\n"
8 析构函数
—-> 8.1 Swift 会自动释放不再需要的实例以释放资源,类似于delloc
—-> 8.2 Swift 通过自动引用计数(ARC)处理实例的内存管理
—-> 8.3 当引用计数为0时,系统会自动调用析构函数(不可以手动调用)
—-> 8.4 通常在析构函数中释放一些资源(如移除通知等操作)
–> 1 析构函数写法
deinit
// 执行析构过程
–> 2 具体代码
class Person : NSObject
var name = ""
var age = 0
//用来释放一些没用的资源,类似于delloc
deinit
print("Person -----deinit") //打印结果 : "Person -----deinit\\n"
NSNotificationCenter.defaultCenter().removeObserver(self)
var p : Person? = Person()
p = nil //此时将p赋值为nil,析构函数中的print会打印Person -----deinit
9 属性监听
—-> 9.1 在OC中我们可以重写set方法来监听属性的改变
—-> 9.2 Swift中可以通过属性观察者来监听和响应属性值的变化
—-> 9.3 通常是监听存储属性和类属性的改变.(对于计算属性,我们不需要定义属性观察者,因为我们可以在计算属性的setter中直接观察并响应这种值的变化)
—-> 9.4我们通过设置以下观察方法来定义观察者
—–> 9.4.1 willSet:在属性值被存储之前设置。此时新属性值作为一个常量参数被传入。该参数名默认为newValue,我们可以自己定义该参数名
—–> 9.4.2 didSet:在新属性值被存储后立即调用。与willSet相同,此时传入的是属性的旧值,默认参数名为oldValue
—–> 9.4.3 willSet与didSet只有在属性第一次被设置时才会调用,在初始化时,不会去调用这些监听方法
class Person: NSObject
//属性监听器name
var name : String = ""
//监听属性即将发生改变
willSet (new)
//在该方法中有一个默认的系统属性newValue,用于存储新值
print(name) //打印结果 : "\\n"
print(new) //打印结果 : "xiaofeng\\n"
//监听属性已经发生改变
didSet (old)
//在该方法中有一个默认的系统属性oldValue,用于存储旧值
print(name) //打印结果 : "xiaofeng\\n"
print(old) //打印结果 : "\\n"
//属性监听器age
var age : Int = 0
//在willSet中有newValue,用于保存新值
willSet (newAge)
print(age)
print(newAge)
//在didSet中有oldSet,用于保存旧值
didSet (oldAge)
print(age)
print(oldAge)
//创建对象
let p = Person()
p.name = "xiaofeng"
p.age = 20
七 总结
1 该部分接上一篇swift基本语法部分,详细的讲解了函数,自定义构造方法,类部分的相关知识,里面写的并不是很全面,我已经尽可能的完善了,希望能帮到大家.
2 最后,我还会陆续的更新swift的相关知识,希望看到我博客的开发者,如果觉得我写的还行的话,麻烦大家支持我的博客,关注我的官方博客,谢谢!!!!
以上是关于swift基本语法的主要内容,如果未能解决你的问题,请参考以下文章