swift语法记录之可选项

2020-04-20  本文已影响0人  LiuffSunny

可选项(optionnal)

// 这样写是会报错的,平常的类型 都不允许赋值为nil
var test: String = "hello"
test = nil

var num: Int = 1
num = nil 
var test: String? = "hello" // 在类型后面加一个问号就是可选项,可以赋值为nil
test = nil

var num: Int? // 默认值是nil
num = nil

var array = [1,20,30,50]
func getvalue(_ index: Int) -> Int? {
    if index < 0 || index >= array.count {
        return nil
    }
    return array[index]
}
print(getvalue(0)) //optional(1)
print(getvalue(-1)) //nil
print(getvalue(4)) //nil

强制解包!

可选项可以理解为一个盒子,强制解包只是把内容取出来,并不会改变可选项的类型


var num: Int? = 10// 默认值是nil
var sum = num! + 20 // 30
print(num) // "Optional(10)

判断可选项是否包含值

var age = Int("123") // age为Int?可选项类型
if age != nil {
    print("字符串转整数,转换成功\(age!)")
}else{
    print("字符串转整数,转换失败")
}

可选项绑定

1.可选项绑定可以用来判断可选项类型是否包含值
2.如果包含就自动解包,把值赋给一个常量(let)或者一个变量(var),并返回true,否则返回false.

if let age = Int("123") {
    print("字符串转整数,转换成功\(age)")
    // age的值是强制解包后的Int值(不再是可选项类型,所以不用加!)
    // age的作用域仅限于这个大括号
}else{
    print("字符串转整数,转换失败")
}
// 对于枚举来说 Season(rawValue: 6)返回的也是可选项
enum Season: Int {
    case spring = 1,summer,autumn,winter
}
if let season = Season(rawValue: 6) {
    print("找得到相应的季节\(season)")
}else{
    print("找不到相应的季节")
}

如下图的第二种,可选项绑定同时要求成立的条件要用逗号,不能用&&符号,要注意此语法问题:

while循环中使用可选项绑定

空合并运算符(返回类型取决于右边的b,从源码可以看出返回值的类型跟随后面那个值)

// 多个空合并运算符一起使用
var a: Int? = 1
var b: Int? = 2
var c = a ?? b ?? 3 // c 是Int,1

// 可选项绑定 if let 和空合并运算符 ?? 一起使用
var a: Int? = nil
var b: Int? = 2
if let c = a ?? b {
    print(c)
}
// 类似于 a != nil || b != nil
if let c = a,let d = b {
     print(c)
     print(d)
}
// 类似于 a != nil && b != nil

guard语句

image.png
// 比起if判断来说要简化很多
func login(_ info: [String : String]) {
    guard let userName = info["userName"] else { // 注意else 是语法的一部分
        print("用户名不能为空")
        return // return必须写
    }
    guard let password = info["password"] else {
        print("密码不能为空")
        return
    }
    // userName 和 password的作用域不仅限于大括号
    print("userName:\(userName)","password:\(password)")
}
login(["userName":"liu","password":"123456"])

隐式解包(开发中不建议使用)

字符串插值

多重可选项

可以使用lldb指令来查看区别 fr v -R 或者 frame variable -R
查看结构

var num1: Int? = 10
var num2: Int?? = num1
var num3: Int?? = 10
(lldb) fr v -R num1
(Swift.Optional<Swift.Int>) num1 = some {
  some = {
    _value = 10
  }
}
(lldb) fr v -R num2
(Swift.Optional<Swift.Optional<Swift.Int>>) num2 = some {
  some = some {
    some = {
      _value = 10
    }
  }
}
(lldb) fr v -R num3
(Swift.Optional<Swift.Optional<Swift.Int>>) num3 = some {
  some = some {
    some = {
      _value = 10
    }
  }
}
此时num2 == num3
另一种为nil的情况: 结构会变得不一样 
var num1: Int? = nil
var num2: Int?? = num1
var num3: Int?? = nil
(lldb) fr v -R num1
(Swift.Optional<Swift.Int>) num1 = none {//当=none后面的内容可不必再查看
  some = {
    _value = 0
  }
}
(lldb) fr v -R num2
(Swift.Optional<Swift.Optional<Swift.Int>>) num2 = some {// = some说明后面的内容还得继续查看
  some = none {
    some = {
      _value = 0
    }
  }
}
(lldb) fr v -R num3
(Swift.Optional<Swift.Optional<Swift.Int>>) num3 = none {
  some = some {
    some = {
      _value = 0
    }
  }
}
此时 num1 和num3 也并不等价
上一篇下一篇

猜你喜欢

热点阅读