目录
- 版本
- 基本语法
- 数据类型
- 常量和变量
- 类型安全/推断/转换
- 可选类型
版本
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)")
}
网友评论