iOS开发之Swift篇(2)—— 基础部分

版本

Xcode 11.0
Swift 5.1

基本语法

1. Swift 引入

我们可以使用 import 语句来引入任何的 Objective-C 框架(或 C 库)到 Swift 程序中。例如 import cocoa 语句导入了使用了 Cocoa 库和API,我们可以在 Swift 程序中使用他们。
使用本工程swift文件无需import, 可直接使用。

2. 注释

// 单行注释
/* 多行注释1
多行注释2 */
/* 嵌套注释1
/* 嵌套注释内容 */
嵌套注释2 */

3. 分号

OC代码行尾需加分号";"(甚至加两个分号都不报错), 而Swift不需要加分号, 如喜欢也可加一个分号(加两个分号会报错). 如果两句代码写在同一行, 则需要分号隔开.

print("111"); print("222")

4. Swift 空格

Swift语言并不是像C/C++,Java那样完全忽视空格,Swift对空格的使用有一定的要求,但是又不像Python对缩进的要求那么严格。在Swift中,运算符不能直接跟在变量或常量的后面。
错误:

let a= 1 + 2    // 报错  error: prefix/postfix '=' is reserved
let a = 1+ 2    // 报错  因为Swift认为到1+这个语句就结束了,2就是下一个语句了

正解:

let a = 1 + 2   // 编码规范推荐使用这种写法
let b = 3+4     // 这样也是OK的

5. 打印输出

Swift 使用 print 函数打印输出:

print("Hello, world!")    // 输出字符串 Hello, world!

print 函数是一个全局函数,完整的函数声明为:

public func print(items: Any..., separator: String = default, terminator: String = default)

如果我们想让其不换行输出,只需要将最后一个参数赋值为空字符串即可:

for x in 0...10{
    
    
    print("\(x) ", terminator: "")
}
print()    // 加这句是为了在for打印结束后换行

Swift 用字符串插值(string interpolation)的方式把常量名或者变量名当做占位符加入到长字符串中,Swift 会用当前常量或变量的值替换这些占位符。将常量或变量名放入圆括号中,并在开括号前使用反斜杠将其转义:

let aa = "abc"
print("字符串 aa = \(aa)")
// 打印输出 字符串 aa = abc

数据类型

Swift 包含了 C 和 Objective-C 上所有基础数据类型,Int 表示整型值; Double 和 Float 表示浮点型值; Bool 是布尔型值;String 是文本型数据。 Swift 还提供了三个基本的集合类型,Array、Set 和 Dictionary。
除了我们熟悉的类型,Swift 还增加了 Objective-C 中没有的高阶数据类型比如元组(Tuple)。元组可以让你创建或者传递一组数据,比如作为函数的返回值时,你可以用一个元组可以返回多个值。
Swift 还增加了可选(Optional)类型,用于处理值缺失的情况。可选表示 “那儿有一个值,并且它等于 x ” 或者 “那儿没有值” 。可选有点像在 Objective-C 中使用 nil ,但是它可以用在任何类型上,不仅仅是类。可选类型比 Objective-C 中的 nil 指针更加安全也更具表现力,它是 Swift 许多强大特性的重要组成部分。
综上, Swift中数据类型包含但不限于以下:

  • Int
  • Double/Float
  • Bool
  • String
  • Array
  • Set
  • Dictionary
  • Tuple

常量和变量

常量和变量把一个名词(比如 age)和一个指定类型的值(比如数字 18)关联起来。常量的值一旦设定就不能改变,而变量的值可以随意更改。

1. 声明

常量和变量必须在使用前声明,用 let(让) 来声明常量,用 var(variable) 来声明变量。

let a = 0
var b = 1
let c = 2, d = 33.3

2. 类型注解

当你声明常量或者变量的时候可以加上类型注解(type annotation),说明常量或者变量中要存储的值的类型。如果不写注解也是可以的, Swift 可以推断出这个常量或者变量的类型, 详见后文类型推断.

var aa:String = "aa"
var bb, cc: String    // 两个一起注解不能直接赋值
bb = "bb"
cc = "cc"
print(aa, bb, cc)

类型安全/推断/转换

1. 类型安全

Swift 是一个类型安全(type safe)的语言。类型安全的语言可以让你清楚地知道代码要处理的值的类型。如果你的代码需要一个 String,你绝对不可能不小心传进去一个 Int。

var name = "XiaoMing"
name = 18    // 报错 Cannot assign value of type 'Int' to type 'String'

2. 类型推断

由于 Swift 是类型安全的,所以它会在编译你的代码时进行类型检查(type checks),并把不匹配的类型标记为错误。
如果你没有显式指定类型 (上文提到的类型注解),Swift 会使用类型推断(type inference)来选择合适的类型。有了类型推断,编译器可以在编译代码的时候自动推断出表达式的类型。原理很简单,只要检查你赋的值即可。

let age = 18
// age 会被推测为 Int 类型

let pi = 3.14159
// pi 会被推测为 Double 类型 (当推断浮点数的类型时,Swift 总是会选择 Double 而不是 Float。)

let anotherPi = 3 + 0.14159
// anotherPi 会被推测为 Double 类型

3. 类型转换

要将一种数字类型转换成另一种,你要用当前值来初始化一个期望类型的新数字,这个数字的类型就是你的目标类型。
例如,常量 aa 是 UInt16 类型,然而常量 bb 是 UInt8 类型。它们不能直接相加,因为它们类型不同。所以要调用 UInt16(bb) 来创建一个新的 UInt16 数字并用 bb 的值来初始化,然后使用这个新数字来计算:

let aa: UInt16 = 800
let bb: UInt8 = 1
let cc = aa + UInt16(bb)

注: omeType(ofInitialValue) 是调用 Swift 构造器并传入一个初始值的默认方法。在语言内部,UInt16 有一个构造器,可以接受一个 UInt8 类型的值,所以这个构造器可以用现有的 UInt8 来创建一个新的 UInt16。注意,你并不能传入任意类型的值,只能传入 UInt16 内部有对应构造器的值。不过你可以扩展现有的类型来让它可以接收其他类型的值(包括自定义类型)。

同样的, 整数和浮点数的转换必须显式指定类型:

let three = 3
let dec = 0.14159
let pi = Double(three) + dec

ps: 所谓显式, 指代码标明且能体现出来, 比如上文的Double(three)转换;
隐式, 比如C中 float aa = 1; 1是int类型, 但赋予aa的时候被隐式转换成了float.

可选类型

可选类型(optionals)用来表示有值或者没有值两种情况. 有值, 才可以解析可选类型访问这个值.

注: C 和 Objective-C 中并没有可选类型这个概念。最接近的是 Objective-C 中的一个特性,一个方法要不返回一个对象要不返回 nil,nil 表示“缺少一个合法的对象”。然而,这只对对象起作用——对于结构体,基本的 C 类型或者枚举类型不起作用。对于这些类型,Objective-C 方法一般会返回一个特殊值(比如 NSNotFound)来暗示值缺失。这种方法假设方法的调用者知道并记得对特殊值进行判断。然而,Swift 的可选类型可以让你暗示任意类型的值缺失,并不需要一个特殊值。

先来看个例子:

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
print(possibleNumber)
print(convertedNumber)    // 警告

// 打印结果
// 123
// Optional(123)

convertedNumber 被推测为类型 “Int?”, 或者类型 “optional Int”. 因为Int()并不能总是返回一个int类型, 传入"123"能返回值123, 而传入"Hello, world"则没有返回值.

1. 写法

var possibleNumber: Int? = 123

2. nil

如果你声明一个可选常量或者变量但是没有赋值,它们会自动被设置为 nil:

var aa: String?
// aa 被自动设置为 nil

可以手动设置为nil:

var aa: Int? = 11    // aa 包含一个可选的 Int 值 11
aa = nil             // 手动设置为nil

注意:
Swift 的 nil 和 Objective-C 中的 nil 并不一样。在 Objective-C 中,nil 是一个指向不存在对象的指针。在 Swift 中,nil 不是指针——它是一个确定的值,用来表示值缺失。任何类型的可选状态都可以被设置为 nil,不只是对象类型。

3. 强制解析

当你确定可选类型确实包含值之后,你可以在可选的名字后面加一个感叹号(!)来获取值。这个惊叹号表示“我知道这个可选有值,请使用它。”这被称为可选值的强制解析(forced unwrapping):

let aa:String? = "123"
print(aa!)
print("字符串 aa = \(aa!)")

注意:
使用 ! 来获取一个不存在的可选值会导致运行时错误。使用 ! 来强制解析值之前,一定要确定可选包含一个非 nil 的值。

4. 隐式解析

有时候在程序架构中,第一次被赋值之后,可以确定一个可选类型总会有值。在这种情况下,每次都要判断和解析可选值是非常低效的,因为可以确定它总会有值。
这种类型的可选状态被定义为隐式解析可选类型(implicitly unwrapped optionals)。把想要用作可选的类型的后面的问号(String?)改成感叹号(String!)来声明一个隐式解析可选类型。
例如:

let possibleString: String? = "An optional string."
let forcedString: String = possibleString!  // 需要感叹号来获取值

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString  // 不需要感叹号

print(assumedString!)    // 仍然需要感叹号, 知道的朋友望不吝赐教.

5. 可选绑定

使用可选绑定(optional binding)来判断可选类型是否包含值,如果包含就把值赋给一个临时常量或者变量。可选绑定可以用在 if 和 while 语句中,这条语句不仅可以用来判断可选类型中是否有值,同时可以将可选类型中的值赋给一个常量或者变量。
例如:

let aa:String? = "abc"
if let bb = aa {
    
    
    print("aa有值 \(bb)")
}

猜你喜欢

转载自blog.csdn.net/u012078168/article/details/103601212