美文网首页iOS Developer
Swift语法学习笔记1:变量与数据类型

Swift语法学习笔记1:变量与数据类型

作者: xueyuios | 来源:发表于2016-08-17 09:17 被阅读0次

我把自己学习Swift语法的笔记通过4篇左右的文章分享给大家。由于是个人笔记,代码较多,配的文字很少,对于Swift初学者的理解可能会造成一些困难。

我会在《Swift语法学习笔记》系列中覆盖以下内容:

  • Swift常量与变量
  • Swift常用数据类型
    • 基本数据类型
    • 集合类型
    • 可选类型
  • 流程控制
    • if语句
    • for循环
    • while语句
    • repeat语句
    • Switch语句
  • 函数和闭包
    • 函数
    • 闭包
  • 结构体
    • 定义与使用结构体
    • 结构体的初始化方法
    • 继承

本篇是《Swift语法学习笔记》系列的第一篇文章,将涵盖以下内容:

  • Swift常量与变量
  • Swift常用数据类型
    • 基本数据类型
      • 整型
      • 字符串类型
      • 布尔类型
      • 枚举类型
    • 集合类型
      • 数组
      • 字典
      • Sets
      • NSArray、NSDictionary、NSSet
    • 可选类型
      • Swift郑家可选类型的原因
      • 获取可选类型的真实值
      • 获取字典中不存在的默认值
      • 枚举类型中的可选类型
      • as与as!的区别
      • as?

1 常量与变量

1.1 常量

Swift使用let声明常量,必须在声明的同时进行初始化赋值,且其值不可更改。

1.2 变量

Swift使用var声明变量:

var str = "Hello World!"    //Swift会自动推定str的类型为String,编译器一旦完成类型推定,此后的代码均不可以修改变量的类型

或者

var str : String
str = "Hello World"

2 数据类型

2.1 基本数据类型

2.1.1 Int整型

获取Int数据类型的最小值与最大值:

Int8.min
Int8.max
UInt32.min
UInt32.max

各种进制的表示方法:

let decimal = 123        // Value is 123
let octal = 0o77         // Octal 77 = decimal 63
let hex = 0x1234         // Hex 1234 = decimal 4660
let binary = 0b1010      // Binary 1010 = decimal 10

为了更好的可读性,在赋值时可以使用“_”分隔数字:

let v = -1_234     // Same as -1234
let w = 12_34_56   // Same as 123456

声明常量的同时指定数据类型:

let a = 1.23         // This is inferred to be a Double
let b: Float = 1.23  // Forced to be Float

Swift不可以做如下形式的类型推定:

let a = 123
let b = 0.456
let c = a + b  //由于a为Int类型,b为Double类型,所以编译器不能决定c到底是什么类型

若要成功编译,需要将a转换为Double类型

let a = 123
let b = 0.456
let c = Double(a) + b

2.1.2 String类型

使用转译符“\”在字符串中插入双引号:

let quoted = "Contains \"quotes\"" // Contains "quotes"

插入反斜杠:

let backslash = "\\" // Result is \

插入换行符与缩进符:

let specialChars = "Line1\nLine2\tTabbed"

插入数值:

print("The value of pi is \(M_PI)") // Prints "The value of pi is 3.14159265358979\n"

插入表达式:

// This code prints: "Area of a circle of radius 3.0 is 28.2743338823081\n"
let r = 3.0
print("Area of a circle of radius \(r) is \(M_PI * r * r)")

字符串相加:

let s = "That's one small step for man, " + "one giant leap for mankind"
print(s)         // "That's one small step for man, one giant leap for mankind\n"

比较字符串:

let s1 = "String one"
let s2 = "String two"
let s3 = "String " + "one"
s1 == s2         // false: strings are not the same
s1 != s2         // true: strings are different
s1 == s3         // true: strings contain the same characters.

获取字符串的长度:

s3.characters.count  // 10
s3.utf16.count       // 10

字符类型只能包含一个字符,且必须用双引号包围。

let c: Character = "s"

不能使用“+”运算符将字符串与字符相加,需要使用字符串的append方法:

let c: Character = "s"
var s = "Book"   // "var" because we want to modify it
s += c           // Error – illegal
s.append(c)      // "Books"

Swift中的字符串等简单数据类型都是“拷贝类型”(只有类除外,类是“引用类型”):

var s1 = "Book"
var s2 = s1     // s2 is now a copy of s1
s2 += "s"       // Appends to s2; s1 is unchanged
s1     // "Book"
s2     // "Books"

2.1.3 Bool类型

var b = true // Inferred type is Bool
var b1: Bool
b1 = false

2.1.4 enum枚举类型

定义枚举类型:

enum DaysOfWeek {
    case Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
}

或者

enum DaysOfWeek {
    case Sunday
    case Monday
    case Tuesday
    case Wednesday
    case Thursday
    case Friday
    case Saturday
}
var day = DaysOfWeek.Sunday       // "day" is inferred to be of type "DaysOfWeek"
day = .Friday                     // Note that the "." Is required

包含其他数据类型的枚举:

enum Status {
    case OK
    case ERROR(String)
}
let status = Status.OK
let failed = Status.ERROR("That does not compute")    //这里的failed被推定为什么类型?

含有原始值的枚举:

enum DaysOfWeek : Int {
    case Sunday = 0 // 0
    case Monday     // 1
    case Tuesday    // 2
    case Wednesday  // 3
    case Thursday   // 4
    case Friday     // 5
    case Saturday   // 6
}

或者

enum DaysOfWeek : Int {
    case Sunday = 0
    case Monday         // 1
    case Tuesday        // 2
    case Wednesday      // 3
    case Thursday       // 4
    case Friday = 20    // 20
    case Saturday       // 21
}
var day = DaysOfWeek.Saturday
let rawValue = day.rawValue         // 21 rawValue位Int类型

原始值为字符串的枚举:

enum ResultType : String {
    case SUCCESS = "Success"
    case WARNING = "Warning"
    case ERROR = "Error"
}
let s = ResultType.WARNING.rawValue     // s = "Warning"为String类型

通过指定枚举类型的原始值可以获取对应的“枚举值”:

let result = ResultType(rawValue: "Error")      // 返回ERROR,result的类型为ResultType?可选类型,具体可以参照“3 可选类型”

2.2 集合类型

2.2.1 数组

声明数组:

var integers = [1, 2, 3]
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]

或者

var integers: [Int] // [Int] means "array of Ints"
integers = [1, 2, 3]

空数组

var empty: [String] = []

数组的索引范围:

var integers = [1, 2, 3]
integers[1..<3]               // Get elements 1 and 2 as an array. Result is [2, 3]
integers[1..<3] = [4]         // Replace elements 1 and 2 with [4]. Result is [1, 4]
integers = [1, 2, 3]
integers[0...1] = [5, 4]      // Replace elements 0 and 1 with [5, 4]. Result is [5, 4, 3]

增加新元素:

var integers = [1, 2, 3]
integers.append(4)             // Result is [1, 2, 3, 4]

或者

integers.insert(-1, atIndex: 0)     // Result is [-1, 1, 2, 3, 4]

或者

var integers = [1, 2, 3]
let a = integers + [4, 5]      // a = [1, 2, 3, 4, 5]; integers array unchanged
integers += [4, 5]             // Now integers = [1, 2, 3, 4, 5]

删除元素:

var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
days.removeAtIndex(3)               // Removes "Wednesday" and returns it to the caller
days.removeRange(0..<4)             // Leaves ["Friday", "Saturday"]
days.removeAll(keepCapacity: false) // Leaves an empty array

常量数组一旦初始化,不可更改其值:

let integers = [1, 2, 3]       // Constant array
integers = [4, 5, 6]           // Error: cannot replace the array
integers[0] = 2                // Error: cannot reassign elements
integers.removeAll(keepCapacity: false)     // Error: cannot modify content

验证复制特性:

var integers = [1, 2, 3]
var integersCopy = integers    // Creates a copy of "integers"
integersCopy[0] = 4            // Does not change "integers"
integers          // [1, 2, 3]
integersCopy      // [4, 2, 3]

检查数组中是否存在某个值:

let integers = [1, 2, 3]
integers.contains(2) // true
integers.contains(4) // false

获取数组中某个值的索引值:

let integers = [1, 2, 3]
let index = indexOf(3)!.value // Result is 2

2.2.2 字典

声明一个类型为[String, Int](<String, Int>)的字典:

var dict = ["Red": 0,
            "Green": 1,
            "Blue": 2]

或者

var dict: [String: Int]
dict = ["Red": 0, "Green": 1, "Blue": 2]

获取字典值:

let value = dict["Red"]         // Result is 0, the value mapped to the key "Red"

获取字典的键值对总数:

var dict = ["Red": 0, "Green": 1, "Blue": 2]
dict.count     // 3

修改字典值:

dict["Yellow"] = 3     // Adds a new value with key Yellow
dict["Red"] = 4        // Updates the value with key Red

删除字典值:

var dict = ["Red": 0, "Green": 1, "Blue": 2]
dict.removeValueForKey("Red")     // Removes value with key "Red"
dict.removeAll()                  // Empties the dictionary

常量字典不能修改:

let fixedDict = ["Red": 0, "Green": 1, "Blue": 2]
fixedDict["Yellow"] = 3             // Illegal
fixedDict["Red"] = 4                // Illegal
fixedDict = ["Blue", 7]             // Illegal
fixedDict.removeValueForKey["Red"]  // Illegal

2.2.3 集合Sets(无序数组)

声明Set:

let s1 = Set([1, 2, 3])

或者

let s2: Set<Int> = [1, 2, 3]

是否含有某元素:

s1.contains(1)  // true
s2.contains(4)  // false
s1.count        // 3

增加元素:

var s1 = Set([1, 2, 3])  // [2, 3, 1] (note that order does not matter in a set)
s1.insert(4)             // [2, 3, 1, 4]

删除元素:

s1.remove(1)           // [2, 3, 4]
s1.removeAll()         // [] (empty set)

2.2.4 NSArray, NSDictionary and NSSet

声明一个NSString:

let s: NSString = "Red,Green,Blue"

使用NSString:

let s: NSString = "Red,Green,Blue"
let components = s.componentsSeparatedByString(",") // Calls the NSString method
components     //[String]类型的["Red", "Green", "Blue"]

使用NSDictionary:

let d = NSDictionary()

强制转换

let e = d as Dictionary

或者

let d = NSDictionary()
let e = d as! [String: String]

2.3 可选类型

2.3.1 Swift增加可选类型的原因

var dict: [String: Int];
dict = ["Red": 0, "Green": 1, "Blue": 2]
let value = dict["Red"]         //the inferred type for value is not Int, but Int?—an optional integer

Swift中为什么会增加可选类型呢?考虑这种情况:

let yellowValue = dict["Yellow"]

What value should be assigned to yellowValue? Most languages address this by having a distinguished value that means, by convention, “no value.” In Objective-C, this value is referred to as nil (which is really just a redefinition of 0); in C and C++ it’s NULL (again, a redefinition of 0); and in Java it’s null.
The problem with this is that it can be dangerous to use a nil (or equivalent) value. In Java, for example, using a null reference causes an exception; in C and C++, the application is likely to crash.What's worse, there's no way to know from its declaration whether a variable might contain a null (or nil or NULL) value.
Swift solves this problem in a neat way: it has a nil value, but a variable (or constant) can only be set to nil if it's declared as an optional, or its type is inferred to be optional. As a result, you can tell immediately whether a variable or constant could be nil by examining its type: if it's not optional, it can't be nil. Further to that, Swift requires you to take that into account explicitly whenever you use the value.

不能赋值nil给非可选类型赋值nil:

var color = "Red"
color = nil     // Illegal: color is not an optional type.

不能赋值可选类型给非可选类型:

let dict = [0: "Red", 1: "Green", 2: "Blue"]
color = dict[0]     // Illegal: value of dict[0] is optional string, color is not optional.

可以将可选类型赋值给可选类型(或者未初始化的常量与变量):

let dict = [0: "Red", 1: "Green", 2: "Blue"]
var color: String?     // "String?" means optional String,color的值为nil
color = dict[0]        // Legal
print(color)           // printed is not“Red” but Optional("Red"),这其实是一个装箱(wrapped)后的值

2.3.2 获取可选类型的值

为了得到可选类型的实际值,需要对可选类型进行Unwrap(拆箱)操作:

let actualColor = color!         // "color!" means unwrap the optional, actualColor是String类型

上面的操作其实可以理解为强制拆箱操作,不论其值是否真的存在,这么做其实是很危险的。试看以下操作:

let dict = [0: "Red", 1: "Green", 2: "Blue"]
let color = dict[4]          //color是String?类型,其值为nil
let actualColor = color!     //对值nil的可选类型进行拆箱,会造成程序崩溃

为了避免发程序崩溃,需要对可选类型进行安全检查:

if color != nil {
    let actualColor = color!
}

或者

if let actualColor = color {
    // Executed only if color was not nil
    print(actualColor)
}

或者

if var actualColor = color {
    // Executed only if color was not nil. actualColor can be modified
    print(actualColor)
}

或者

if var color = color {
    // Executed only if the value of the original color variable was not nil
    print(color) // Refers to the new variable, holding the unwrapped value
}

或者

let dict = [0: "Red", 1: "Green", 2: "Blue"]
let color = dict[0]
if var color = color {
    // Executed only if color was not nil
    print(color)         // "Red"
    color = "Green"       // Reassigns the local variable
}         // New color variable is now out of scope
color     // Refers to the original value: "Red"

2.3.3 获取字典中不存在的默认值

let dict = [0: "Red", 1: "Green", 2: "Blue"]
let color = dict[4]
let actualColor = color ?? "Blue"

或者

let dict = [0: "Red", 1: "Green", 2: "Blue"]
let actualColor = dict[4] ?? "Blue"

2.3.4 枚举类型中的可选类型

enum ResultType : String {
    case SUCCESS = "Success"
    case WARNING = "Warning"
    case ERROR = "Error"
}
let result = ResultType(rawValue: "Invalid")     //result为ResultType?类型,其值为nil

!可选类型的作用:

let dict = [0: "Red", 1: "Green", 2: "Blue"]
var color: String!         // Notice the !,这个操作告诉编译器color永远不可能为    nil值
color = dict[0]            // Assigns Optional("Red")
print(color)               // Automatically unwraps the optional

2.3.5 as与as!的区别

Roughly speaking, you use as when the cast is guaranteed to work and as! when it’s not—the ! expresses the fact that you are forcing the compiler to accept code that it would otherwise report an error for, such as when downcasting.

as可以用于子类向父类的转换:

let s = "Fred"
let n = s as NSString

或者

let label = UILabel()
let view = label as UIView

as!用于父类向子类的强制转换,或未知类向任意类的转换:

let view: UIView = UILabel()
let label = view as! UILabel     // Downcast requires !

或者

let d = NSDictionary(objects: ["Red", "Green", "Blue"], forKeys: [0, 1, 2])
let color = d[1] as! String

2.3.6 as?

let d = NSDictionary(objects: ["Red", "Green", "Blue"], forKeys: [0, 1, 2])

获取值:

let color = d[1]     // Gets an optional-AnyObject?, wrapping "Green"

或者

let color = d[1] as! String

注意以下的错误代码:

let d = NSDictionary(objects: [ 0, 1, 2], forKeys: [0, 1, 2])
let value = d[1] as! String     //crash happened

为了防止这种情况发生,需要使用as?:

The as? operator returns an optional: if its first operand is not of the type given by its second operand, it returns nil instead of crashing

let d = NSDictionary(objects: [ 0, 1, 2], forKeys: [0, 1, 2])
if let value = d[1] as? String {     // as? returns nil if d is not of type String?
    print("OK")     // As expected – use value as normal
} else {
    print("Incorrect types")     // Executed if d is not of type [Int: String]
}

或者

You can use the is keyword to check whether the dictionary is of the expected type before using it:

if d is [Int: String] { // Evaluate to true if d maps Ints to Strings
    print("Is [Int: String]")
} else {
    print("Incorrect types")
}

参考文献

《Beginning iPhone Development with Swift 2 - Exploring the iOS SDK 》From page 777 to page 838.

联系作者

相关文章

  • Swift基本语法之函数

    Swift基本语法之初体验-常量变量-数据类型 Swift基本语法之逻辑分支 Swift基本语法之循环 Swift...

  • Swift基本语法之数组和字典

    Swift基本语法之初体验-常量变量-数据类型 Swift基本语法之逻辑分支 Swift基本语法之循环 Swift...

  • Swift基本语法之元组和可选类型

    Swift基本语法之初体验-常量变量-数据类型 Swift基本语法之逻辑分支 Swift基本语法之循环 Swift...

  • Swift基本语法之闭包

    Swift基本语法之初体验-常量变量-数据类型 Swift基本语法之逻辑分支 Swift基本语法之循环 Swift...

  • 000-swift基本语法

    1、swift和OC的区别: 1-1、swift中的语法 1、在swift中只有2中数据类型:常量、变量...

  • Swift基本语法之类的使用

    Swift中类的使用 Swift基本语法之初体验-常量变量-数据类型 Swift基本语法之逻辑分支 Swift基本...

  • Swift基本语法之字符串

    Swift基本语法之初体验-常量变量-数据类型 Swift基本语法之逻辑分支 Swift基本语法之循环 字符串的介...

  • swift学习笔记④

    Swift学习笔记 - 文集 语法篇 一、可选类型 Optional Swift 中,常量和变量是不允许赋予 ni...

  • Swift语法学习笔记1:变量与数据类型

    我把自己学习Swift语法的笔记通过4篇左右的文章分享给大家。由于是个人笔记,代码较多,配的文字很少,对于Swif...

  • Swift基本语法之循环

    Swift基本语法之初体验-常量变量-数据类型 Swift基本语法之逻辑分支 循环的介绍 在开发中经常会需要循环 ...

网友评论

    本文标题:Swift语法学习笔记1:变量与数据类型

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