美文网首页
#1 swift基础知识

#1 swift基础知识

作者: JamesSawyer | 来源:发表于2018-08-18 10:10 被阅读11次

The basic - swift 4.2

1. 基础类型

  • Int
  • Float
  • Double
  • Bool
  • String
  • tuple: 元组,OC中不存在,元组主要可以用于一次性创建或者传递或者返回多个值
  • Optional: 可选类型。类似于OC中的空指针,但是可选类型可以作用于任何类型,不仅仅是classes.

2.常量和变量

常量一旦被定义则不可以再被赋值。常量和变量都需要在被使用前被赋值:

  • var: 用于声明变量
  • let: 用于声明常量

注意和JS中有所区别

// 常量
// 常量声明之后不能更改 否则会报错
let maximumNumberOfLoginAttempts = 10

// 变量
var currentLoginAttempt = 0
var x = 0.0, y = 0.0, z = 0.0 // 同时声明多个变量 这种形式和JS一个样

// 变量声明之后还可以更改
currentLoginAttempt = 2

3.类型注释

例如:

var welcomeMessage: String;
welcomeMessage = "Hello";

var red, blue, yellow: Double;
// 表示的是 red, blue, yellow 都是 Double 类型
// 等价于
var red: Double
var blue: Double
var yellow: Double

一般我们可以不用定义变量的类型,因为Swift会 隐式类型推断(Type Inference)

4.分号

swift中分号 ; 和JS一样也是可选的,可以加上,也可以去掉,目前看来不使用分号的比较多

let name = "james"; print(name) // ok

// Ok
let age = 18
print(String(age))

5.整型(Integers)

Swift 提供 8, 16, 32, 64 位有符(signed: positive, zero, negative)或者无符(unsigned: positive or zero) 类型的整型。例如

  • UInt8
  • Int8
  • UInt16
  • Int16

5.1 整型边界(Integer Bounds)

可以使用 min | max 属性来访问最大值或者最小值

let minValue = UInt8.min  // 0
let maxValue = UInt8.max  // 255

5.2 Int

大多数情况下,不需要特意选择特别的整型类型,Swift提供了 Int 类型,它对所处平台保持一致的字节数:

  • 32-bit 平台,Int和 Int32 字节数一样
  • 64-bit 平台,Int和 Int64 字节数一样

即使在32位平台上,Int类型也能够存储 -2,147,483,6482,147,483,647 区间范围的值。

5.3 UInt

只有在需要无符整型类型的时候才使用 UInt,同样这个类型会和所处平台的字节保持一致

6.浮点(Float | Double)

浮点能够表示的范围比整型更加的宽广,能够存储比Int更大的或者更小的书:

  • Double: 64位双精度浮点, 至少小数点15位,更偏向于使用Double类型的浮点数
  • Float: 32位单精度浮点数,小数点6位

将整型强转为Double类型

// 这个和强转为 String 类型一样, String(10)
let a = 10
let b = 3.14
// 抛出错误 Error
// error: binary operator '+' cannot be applied to operands of type 'Int' and 'Double'
let c = a + b


// 强制转换 OK
let c = Double(a) + b

// 开始使用下面方式进行转换 但是会报错 Error
// error: cannot convert value of type 'Int' to type 'Double' in coercion
let c = (a as Double) + b

7.类型推断(Type Inference)

let meaningOfLift = 42 // 推断为 Int

// 对于浮点数 推断为 Double
let pi = 3.14159

// 推断为 Double
let anotherPi = 3 + 0.14159

8.数字字面量(Numeric Literals)

整型字面量可以写为以下形式:

  • 10进制(decimal),没有前缀
  • 2进制(binary), 0b 作为前缀
  • 8进制(octal), 0o 作为前缀
  • 16进制(hexadecimal), 0x 作为前缀
// 17 的表示
let decimalInteger = 17
let binaryInteger = 0b10001
let octalInteger = 0o21
let hexadecimalInterger = 0x11

浮点字面量可以是10进制,或者16进制的,它们必须在小数点2侧有数字(或者16进制字符)。

  • 10进制浮点可以使用指数,可以是大写的 E 或者 小写的 e
  • 16进制浮点可以使用指数,可以是大写的 P 或者 小写的 p
// 10进制的浮点 带指数
1.25e2 // 表示 1.25 x 10的2次方,或者 125.0
1.25e-2 // 表示 1.25 x 10的负2次方, 或者 0.0125

// 16进制指数
0xFp2 表示 15 x 2的2次方,或者 60.0
0xFp-2 表示 15 x 2的负2次方,或者 3.75

// 表示 12.1875 的方式
let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0

数字字面量包含其它易读的格式。整型和浮点可以使用填充0并且包含下划线来增加可读性

let paddedDouble = 000123.456 // 123.456
let oneMillion = 1_000_000 // 100万 1000000
let justOverOneMillion = 1_000_000.000_000_1 // 100000.0000001

9.类型转换

// UInt (0 - 255) 无符整型
// 不能为负数报错
let cannotBeNegative: UInt8 = -1

// Int8 不能存储大过最大值 报错
let tooBig: Int8 = Int8.max + 1

let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
// 不同类型不能直接相加 需要先进行转换
let result = twoThousand + UInt16(one)

10.类型别名(typealias)

类型别名一般是在某个上下文环境中该别名更加合适,比如:

typealias AudioSample = UInt16

var maxAmplitudeFound = AudioSample.min // 等价于 UInt16.min

11.布尔值(Bool)

swift 的类型安全不允许非布尔值来表示Bool类型,下面示例会报编译错误:

let i = 1
if i {
  // 编译错误
  // error: 'Int' is not convertible to 'Bool'
}

上面的写法在JS中没有半点问题(除开书写语法)

写成下面形式则没有问题:

let i = 1
if i == 1 {
  // OK
}

12.元组(Tuples)

元组中的值可以是任意类型的,可以不相同:

let http404Error = (404, "Not Found") // (Int, String)

可以解耦元组,和JS中的解构一样:

let (statusCode, statusMessage) = http404Error
print("the status code is \(statusCode)")

// 如果想要忽略某个值
// 可以使用 '_' 作为占位符
let (_, statusMessage) = http404Error
print("hi \(httpMessage)") // "hi Not Found"

元组在函数返回值中特别有用,因为它可以返回不同的类型

13.可选类型(Optionals)

在一个值可能缺失的时候使用可选类型。可选类型在OC或者C中是不存在的。在OC中可以返回nil,否则返回object,但是这只对object有用,对结构体,基本的C类型或者枚举值则没用。OC通常返回一个特殊值(NSNotFound) 来表示某个值的缺失。

例如, Int 的初始化器(initializer) 有一个尝试将String类型转换成Int类型的功能

let possibleNumber = "123"
// convertedNumber 被推断为 'Int?' 或者 'optional Int' 类型
// 因为 假如 let possibleNumber = "hello" 则转换会失败
let convertedNumber = Int(possibleNumber) // 123

// 转换失败的情形
let possibleNumber = "hello123"
let convertedNumber = Int(possibleNumber) // nil

可选类型表示可能包涵某个类型的值,也有可能根本不存在该值

可以将可选变量设置为nil

// Int? 类型
var serverResponseCode: Int? = 404

serverResponseCode = nil

// 注意不能将一个非可选类型的常量或者变量设置为nil

如果没有给可选类型设置一个初始值,则默认为nil

var surveyAnswer: String?  // 默认为nil

13.1 if语句和强制解包(forced unwrapping)

可以使用 if 语句通过对比 nil 来查看某个可选变量是否有值

// 如果一个可选变量有值,则将不等于 nil
// 也就是js里面的不为空
if convertedNumber != nil {
  print("convertedNumber 包含某个值")
}

// 再比如
let c: Int? = 0
if c != nil {
    print("hello")
}

强制解包: 假如你100%确认某个可选变量包含某个值,则可以在变量名后添加 ! (感叹号),表示强制解包,意味着可以放心的使用

// 字典
let info: Dictionary? = [
  "name": "James",
  "age": 19
]

// 'info!' 表示对可选类型强制解包
// ?? "Kobe" 表示如果解包失败,则使用默认提供的值("Kobe")
print(info!["name"] ?? "Kobe")

尝试使用 ! 访问一个不存在的可选类型值会导致运行时错误。在使用强制解包前,请确保可选类型包含一个 non-nil(非空值)

13.2 可选绑定(Optional Binding)

使用可选绑定查看是否可选变量是否包含一个值,如果存在值,则将值作为 临时常量或者临时变量。可选绑定可以和 if | while 语句结合使用,既可以检测可选变量是否为空,若非空同时将其赋值给另一个变量

if let constantName = someOptional {
  // statements
}

示例:

let possibleNumber = "123"
// 其中 Int(possibleNumber) 返回的是一个 Int? 类型
// 将转换的结果赋值给常量 actualNumber
if let actualNumber = Int(possibleNumber) {
  print("\" \(possibleNumber) \" 有一个整型值 \(actualNumber)") // 将会打印这句
} else {
  print("转换失败")
}

// 赋值给变量是一样的
if var actualNumber = Int(possibleNumber) {
  print("\" \(possibleNumber) \" 有一个整型值 \(actualNumber)") // 将会打印这句
} else {
  print("转换失败")
}

可以包含多个可选绑定,使用 , 分隔开:

if let firstNum = Int("42"), let secondNum = Int("98"),
firstNum < secondNum && secondNum < 100 {
  print("\(firstNum) < \(secondNum) < 100")
}
// 打印  42 < 98 < 100

// 上面的式子等价于
if let firstNum = Int("42") {
  if let secondNum = Int("98") {
    if firstNum < secondNum && secondNum < 100 {
      print("\(firstNum) < \(secondNum) < 100")
    }
  }
}

13.3 隐式解包可选类型(Implicitly Unwrapped Optionals)

有时在第一次赋值后,可以确定一个可选类型总会有值,这种情况下,每次都要去判断和解析可选类型值是非常低效的,因为可以确定它总会有值。这种类型的可选类型称之为隐式解析(或解包?)可选类型。例如将 String? 写为 String!即可。

隐式解析可选类型主要被用于Swift中类的构造过程中,参考 无主引用以及隐式解析可选属性

一个隐式解析可选类型其实就是一个普通的可选类型,但是可以不需要每次都是用解析来获取可选值

let possibleString: String? = "一个可选字符串"
let forcedString: String = possibleString! // 需要感叹号来获取值
// 如果不适用 ! 进行解析访问 则会报错
// error: value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'
let forcedString: String = possibleString // 报错


// 声明时使用 String! 表示隐式解析可选类型
let assumedString: String! = "一个隐式解析可选字符串"
let implicitString: String = assumedString // 不需要感叹号

你可以把隐式解析可选类型当做一个可以自动解析的可选类型。你要做的只是声明的时候把感叹号放到类型的结尾,而不是每次取值的可选名字的结尾。

可以把隐式解析可选类型当做普通可选类型来判断是否包含值:

let assumedString: String! = "一个隐式解析可选字符串"
let implicitString: String = assumedString // 不需要感叹号
if assumedString != nil {
  print(assumedString)
}

// 也可以在可选绑定中使用饮食街西可选类型来检查并解析它的值
if let definiteStr = assumedString {
  print(definiteStr)
}

14.错误处理(Error Handling)

一个函数可以通过声明中添加 throws 关键词来抛出错误消息。当你的函数能抛出错误消息时,则要在表达式中前置 try 关键词

func canThrowAnError() throws {
  // 这个函数可能抛出错误
}

do {
  try canThrowAnError() // 使用 try
  // 没有错误消息抛出
} catch {
  // 有一个错误消息抛出
}

swift中可以使用多个 catch 语句

func makeSandwich() throws {
  // ...
}

do {
  try makeSandwich()
  eatASandwich() // 上面没有错误 则执行这一行代码
} catch SandwichError.outOfCleanDishes {
  // 如果没有干净盘子了 则去洗盘子
  washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
  // 如果没有了原材料 则去购买原材料
  buyGroceries(ingredients)
}

相关文章

网友评论

      本文标题:#1 swift基础知识

      本文链接:https://www.haomeiwen.com/subject/odoxiftx.html