自己看菜鸟教程做的笔记:
1.如果需要创建一个OS X playground:
import Cocoa
如果需要创建IOS playground 则引入UIKit
import UIKit
2.输出:print()
3.注释:the same as C
4.Swift不要求在每行语句的结尾使用分号(;),但当你在同一行书写多条语句时,必须用分号隔开。
5.对于空格具有要求,注意规范。
let a = 1 + 2;
let b = 3+4
6.接收用户输入:
let theInput = readLine()
7.类型定义:
int a
8.类型别名(类似于C中的typedef)
typealias Feet = Int
var distance: Feet = 100
9. 类型推断:有时候我们不需要自己指定类型,swift会使用类型推断来选择合适的类型。
let meaningOfLife = 42
// meaningOfLife 会被推测为 Int 类型
var varA = 42
10.变量(常量)输出: \()
var name = "菜鸟教程"
var site = "http://www.runoob.com"
print("\(name)的官网地址为:\(site)")
11.可选类型:Swift 的可选(Optional)类型,用于处理值缺失的情况。可选表示"那儿有一个值,并且它等于 x "或者"那儿没有值"。
var optionalInteger: Int?
如果一个可选类型的实例包含一个值,你可以用后缀操作符 !来访问这个值,如下所示:
optionalInteger = 42
optionalInteger! // 42
(1)强制解析:当你确定可选类型确实包含值之后,你可以在可选的名字后面加一个感叹号(!)来获取值。
var myString:String?
myString = "Hello, Swift!"
if myString != nil {
// 强制解析
print( myString! )
}else{
print("myString 值为 nil")
}
(2)自动解析:你可以在声明可选变量时使用感叹号(!)替换问号(?)。这样可选变量在使用时就不需要再加一个感叹号(!)来获取值,它会自动解析。
var myString:String!
myString = "Hello, Swift!"
if myString != nil {
print(myString)
}else{
print("myString 值为 nil")
}
(3)可选绑定:使用可选绑定(optional binding)来判断可选类型是否包含值,如果包含就把值赋给一个临时常量或者变量。
var myString:String?
myString = "Hello, Swift!"
if let yourString = myString {
print("你的字符串值为 - \(yourString)")
}else{
print("你的字符串没有值")
}
12.常量:常量使用关键字 let 来声明。
let constA = 42
(1)类型标注:当你声明常量或者变量的时候可以加上类型标注(type annotation),说明常量或者变量中要存储的值的类型。
let constB:Float = 3.14159
13.字面量:指像特定的数字,字符串或者是布尔值这样,能够直接了当地指出自己的类型并为变量进行赋值的值。
14.Swift3 中已经取消++、--
15.区间运算符(闭区间,半开区间):
print("闭区间运算符:")
for index in 1...5 {
print("\(index) * 5 = \(index * 5)")
}
//1、2、3、4、5
print("半开区间运算符:")
for index in 1..<5 {
print("\(index) * 5 = \(index * 5)")
}
//1、2、3、4
16.在条件语句中,Swift均没有使用括号,直接书写判断条件。
17.循环语句:
在Swift 3之后,最基本的for循环已经被弃用,即for int i = 0; i < 3; i++{}这种写法
for-in: two types:
for index in 1...5 {
print("\(index) 乘于 5 为:\(index * 5)")
}
var someInts:[Int] = [10, 20, 30]
for index in someInts {
print( "index 的值为 \(index)")
}
while: the same as C
repeat...while: the same as do...while in C
18:字符串
创建 two types:
// 使用字符串字面量
var stringA = "Hello, World!"
print( stringA )
// String 实例化
var stringB = String("Hello, World!")
print( stringB )
创建空字符串:
var stringA = ""
let stringB = String()
String()方法得到的是常量,不可修改。
拼接字符串emmm:
var varA = 20
let constA = 100
var varC:Float = 20.0
var stringA = "\(varA) 乘于 \(constA) 等于 \(varC * 100)"
连接字符串:字符串可以通过 + 号来连接。
字符串长度:使用 String.characters.count 属性来计算。
字符串比较:你可以使用 == 来比较两个字符串是否相等。
Unicode字符串:Unicode 是一个国际标准,用于文本的编码,Swift 的 String 类型是基于 Unicode建立的。你可以循环迭代出字符串中 UTF-8 与 UTF-16 的编码。
var unicodeString = "菜鸟教程"
print("UTF-8 编码: ")
for code in unicodeString.utf8 {
print("\(code) ")
}
print("\n")
print("UTF-16 编码: ")
for code in unicodeString.utf16 {
print("\(code) ")
}
isEmpty
判断字符串是否为空,返回布尔值
hasPrefix(prefix: String)
检查字符串是否拥有特定前缀
hasSuffix(suffix: String)
检查字符串是否拥有特定后缀。
Int(String)
转换字符串数字为整型。 实例:
let myString: String = "256"
let myInt: Int? = Int(myString)
unicodeScalars
您可以通过遍历String值的unicodeScalars属性来访问它的 Unicode 标量编码.
<
比较两个字符串,对两个字符串的字母逐一比较。
!=
比较两个字符串是否不相等。
e.g. 字符串分割数组 -- 基于空格
let fullName = "First Last"
let fullNameArr = fullName.characters.split{$0 == " "}.map(String.init)
// or simply:
// let fullNameArr = fullName.characters.split{" "}.map(String.init)
fullNameArr[0] // First
fullNameArr[1] // Last
19.字符
创建:let char1: Character = "A"
Swift 中不能创建空的 Character(字符) 类型变量或常量。
遍历字符串中的字符:
for ch in "Runoob".characters {
print(ch)
}
字符串连接字符:
String.append(Character)
20. 数组
创建数组:
我们可以使用构造语法来创建一个由特定数据类型构成的空数组:
var someArray = [SomeType]()
以下实例创建了一个类型为 Int ,数量为 3,初始值为 0 的空数组:
var someInts = [Int](repeating: 0, count: 3)
以下实例创建了含有三个元素的数组:
var someInts:[Int] = [10, 20, 30]
初始化数组,添加数据:
var someInts = [Int]()
someInts.append(20)
someInts.append(30)
someInts += [40]
var someVar = someInts[0]
print( "第一个元素的值 \(someVar)" )
print( "第二个元素的值 \(someInts[1])" )
print( "第三个元素的值 \(someInts[2])" )
可通过索引修改目标数组元素的值。
遍历数组:
for item in someStrs {
print(item)
}
合并数组:使用加法操作符(+)来合并两种已存在的相同类型数组。
计算数组元素个数: Array.count
判断为空:Array.isEmpty
21.字典:Swift 字典每个值(value)都关联唯一的键(key),键作为字典中的这个值数据的标识符。
创建:
var someDict = [Int: String]()
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
访问:通过key值进行查找
print( "key = 2 的值为 \(someDict[2])" )
修改字典:可以增加或更新字典的内容,注意其返回值为原来的value值。
var oldVal = someDict.updateValue("One 新的值", forKey: 1)
someDict[1] = "One 新的值"
删除key-value对:注意其返回值为原来的value值。
var removedValue = someDict.removeValue(forKey: 2)
someDict[2] = nil
遍历:
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
for (key, value) in someDict {
print("字典 key \(key) - 字典 value \(value)")
}
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
for (key, value) in someDict.enumerate() {
print("字典 key \(key) - 字典 (key, value) 对 \(value)")
}
字典转换为数组(key数组与value数组):
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
let dictKeys = [Int](someDict.keys)
let dictValues = [String](someDict.values)
print("输出字典的键(key)")
for (key) in dictKeys {
print("\(key)")
}
print("输出字典的值(value)")
for (value) in dictValues {
print("\(value)")
}
计数键值对:
someDict1.count
判断为空:
someDictionary.isEmpty
22.函数:
func runoob(site: String) -> String {
return (site)
}
print(runoob(site: "www.runoob.com"))
不带参数:
func sitename() -> String {
return "菜鸟教程"
}
print(sitename())
元组作为函数返回值:
func minMax(array: [Int]) -> (min: Int, max: Int) {
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
let bounds = minMax(array: [8, -6, 2, 109, 3, 71])
print("最小值为 \(bounds.min) ,最大值为 \(bounds.max
无返回值:
func runoob(site: String) {
print("菜鸟教程官网:\(site)")
}
runoob(site: "http://www.runoob.com")
外部参数名:你可以在局部参数名前指定外部参数名,中间以空格分隔,外部参数名用于在函数调用时传递给函数的参数。如下你可以定义以下两个函数参数名并调用它:
func pow(firstArg a: Int, secondArg b: Int) -> Int {
var res = a
for _ in 1..<b {
res = res * a
}
print(res)
return res
}
pow(firstArg:5, secondArg:3)
可变参数:可变参数可以接受零个或多个值。函数调用时,你可以用可变参数来指定函数参数,其数量是不确定的。可变参数通过在变量类型名后面加入(...)的方式来定义。
func vari<N>(members: N...){
for i in members {
print(i)
}
}
vari(members: 4,3,5)
vari(members: 4.5, 3.1, 5.6)
vari(members: "Google", "Baidu", "Runoob")
常量、变量及I/O参数:一般默认在函数中定义的参数都是常量参数,也就是这个参数你只可以查询使用,不能改变它的值。
如果想要声明一个变量参数,可以在参数定义前加 inout 关键字,这样就可以改变这个参数的值了。
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
var x = 1
var y = 5
swapTwoInts(&x, &y)
print("x 现在的值 \(x), y 现在的值 \(y)")
使用函数类型:
func sum(a: Int, b: Int) -> Int {
return a + b
}
var addition: (Int, Int) -> Int = sum
print("输出结果: \(addition(40, 89))")
函数嵌套:
func calcDecrement(forDecrement total: Int) -> () -> Int {
var overallDecrement = 0
func decrementer() -> Int {
overallDecrement -= total
return overallDecrement
}
return decrementer
}
let decrem = calcDecrement(forDecrement: 30)
print(decrem())
23.闭包:闭包(Closures)是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。
let divide = {(val1: Int, val2: Int) -> Int in
return val1 / val2
}
let result = divide(200, 20)
print (result)
sorted 方法
Swift 标准库提供了名为 sorted(by:) 的方法,会根据您提供的用于排序的闭包函数将已知类型数组中的值进行排序。
排序完成后,sorted(by:) 方法会返回一个与原数组大小相同,包含同类型元素且元素已正确排序的新数组。原数组不会被 sorted(by:) 方法修改。(用闭包函数写的排序方式来对数组进行排序)
let names = ["AT", "AE", "D", "S", "BE"]
// 使用普通函数(或内嵌函数)提供排序功能,闭包函数类型需为(String, String) -> Bool。
func backwards(s1: String, s2: String) -> Bool {
return s1 > s2
}
var reversed = names.sorted(by: backwards)
print(reversed)
参数名称缩写:Swift 自动为内联函数提供了参数名称缩写功能,您可以直接通过$0,$1,$2来顺序调用闭包的参数。
let names = ["AT", "AE", "D", "S", "BE"]
var reversed = names.sorted( by: { $0 > $1 } )
print(reversed)
运算符函数
实际上还有一种更简短的方式来撰写上面例子中的闭包表达式。
Swift 的String类型定义了关于大于号 (>) 的字符串实现,其作为一个函数接受两个String类型的参数并返回Bool类型的值。 而这正好与sort(_:)方法的第二个参数需要的函数类型相符合。 因此,您可以简单地传递一个大于号,Swift可以自动推断出您想使用大于号的字符串函数实现:
let names = ["AT", "AE", "D", "S", "BE"]
var reversed = names.sorted(by: >)
print(reversed)
尾随闭包
尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。
func someFunctionThatTakesAClosure(closure: () -> Void) {
// 函数体部分
}
// 以下是不使用尾随闭包进行函数调用
someFunctionThatTakesAClosure({
// 闭包主体部分
})
// 以下是使用尾随闭包进行函数调用
someFunctionThatTakesAClosure() {
// 闭包主体部分
}
捕获值
闭包可以在其定义的上下文中捕获常量或变量。
即使定义这些常量和变量的原域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。
Swift最简单的闭包形式是嵌套函数,也就是定义在其他函数的函数体内的函数。
嵌套函数可以捕获其外部函数所有的参数以及定义的常量和变量。
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
let incrementByTen = makeIncrementor(forIncrement: 10)
// 返回的值为10
print(incrementByTen())
// 返回的值为20
print(incrementByTen())
// 返回的值为30
print(incrementByTen())
闭包是引用类型
上面的例子中,incrementByTen是常量,但是这些常量指向的闭包仍然可以增加其捕获的变量值。
这是因为函数和闭包都是引用类型。
无论您将函数/闭包赋值给一个常量还是变量,您实际上都是将常量/变量的值设置为对应函数/闭包的引用。 上面的例子中,incrementByTen指向闭包的引用是一个常量,而并非闭包内容本身。
这也意味着如果您将闭包赋值给了两个不同的常量/变量,两个值都会指向同一个闭包:
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
let incrementByTen = makeIncrementor(forIncrement: 10)
// 返回的值为10
incrementByTen()
// 返回的值为20
incrementByTen()
// 返回的值为30
incrementByTen()
// 返回的值为40
incrementByTen()
let alsoIncrementByTen = incrementByTen
// 返回的值也为50
print(alsoIncrementByTen())
24.枚举(如果你已经设定了weekDay为DaysofaWeek中的枚举类型,那么在给该变量赋予其他枚举值时可以直接使用.THURSDAY来确定):
// 定义枚举
enum DaysofaWeek {
case Sunday
case Monday
case TUESDAY
case WEDNESDAY
case THURSDAY
case FRIDAY
case Saturday
}
var weekDay = DaysofaWeek.THURSDAY
weekDay = .THURSDAY
switch weekDay
{
case .Sunday:
print("星期天")
case .Monday:
print("星期一")
case .TUESDAY:
print("星期二")
case .WEDNESDAY:
print("星期三")
case .THURSDAY:
print("星期四")
case .FRIDAY:
print("星期五")
case .Saturday:
print("星期六")
}
相关值与原始值(对比来看):
相关值 | 原始值 |
不同数据类型 | 相同数据类型 |
实例: enum {10,0.8,"Hello"} | 实例: enum {10,35,50} |
值的创建基于常量或变量 | .预先填充的值 |
相关值是当你在创建一个基于枚举成员的新常量或变量时才会被设置,并且每次当你这么做得时候,它的值可以是不同的。 | 原始值始终是相同的 |
相关值:
enum Student{
case Name(String)
case Mark(Int,Int,Int)
}
var studDetails = Student.Name("Runoob")
var studMarks = Student.Mark(98,97,95)
switch studMarks {
case .Name(let studName):
print("学生的名字是: \(studName)。")
case .Mark(let Mark1, let Mark2, let Mark3):
print("学生的成绩是: \(Mark1),\(Mark2),\(Mark3)。")
}
原始值:在原始值为整数的枚举时,不需要显式的为每一个成员赋值,Swift会自动为你赋值。当使用整数作为原始值时,隐式赋值的值依次递增1。如果第一个值没有被赋初值,将会被自动置为0。
enum Month: Int {
case January = 1, February, March, April, May, June, July, August, September, October, November, December
}
let yearMonth = Month.May.rawValue
print("数字月份为: \(yearMonth)。")
25.结构体:
结构体不需要包含实现文件和接口。
结构体允许我们创建一个单一文件,且系统会自动生成面向其它代码的外部接口。
struct MarkStruct{
var mark1: Int
var mark2: Int
var mark3: Int
}
struct studentMarks {
var mark1 = 100
var mark2 = 78
var mark3 = 98
}
let marks = studentMarks()
print("Mark1 是 \(marks.mark1)")
print("Mark2 是 \(marks.mark2)")
print("Mark3 是 \(marks.mark3)")
struct MarksStruct {
var mark: Int
init(mark: Int) {
self.mark = mark
}
}
var aStruct = MarksStruct(mark: 98)
26.类
class MarksStruct {
var mark: Int
init(mark: Int) {
self.mark = mark
}
}
class studentMarks {
var mark = 300
}
let marks = studentMarks()
print("成绩为 \(marks.mark)")
恒等运算符:
因为类是引用类型,有可能有多个常量和变量在后台同时引用某一个类实例。
为了能够判定两个常量或者变量是否引用同一个类实例,Swift 内建了两个恒等运算符:
class SampleClass: Equatable {
let myProperty: String
init(s: String) {
myProperty = s
}
}
func ==(lhs: SampleClass, rhs: SampleClass) -> Bool {
return lhs.myProperty == rhs.myProperty
}
let spClass1 = SampleClass(s: "Hello")
let spClass2 = SampleClass(s: "Hello")
if spClass1 === spClass2 {// false
print("引用相同的类实例 \(spClass1)")
}
if spClass1 !== spClass2 {// true
print("引用不相同的类实例 \(spClass2)")
}
输出:
引用不相同的类实例 SampleClass
26.属性
struct Number
{
var digits: Int
let pi = 3.1415
}
var n = Number(digits: 12345)
n.digits = 67
print("\(n.digits)")
print("\(n.pi)")
延迟存储属性:
延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性。
在属性声明前使用 lazy 来标示一个延迟存储属性。
必须将延迟存储属性声明成变量(使用var关键字),因为属性的值在实例构造完成之前可能无法得到。而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性。
class sample {
lazy var no = number() // `var` 关键字是必须的
}
class number {
var name = "Runoob Swift 教程"
}
var firstsample = sample()
print(firstsample.no.name)
除存储属性外,类、结构体和枚举可以定义计算属性,计算属性不直接存储值,而是提供一个 getter 来获取值,一个可选的 setter 来间接设置其他属性或变量的值。
class sample {
var no1 = 0.0, no2 = 0.0
var length = 300.0, breadth = 150.0
var middle: (Double, Double) {
get{
return (length / 2, breadth / 2)
}
set(axis){
no1 = axis.0 - (length / 2)
no2 = axis.1 - (breadth / 2)
}
}
}
var result = sample()
print(result.middle)
result.middle = (0.0, 10.0)
print(result.no1)
print(result.no2)
(150.0, 75.0)
-150.0
-65.0
只有 getter 没有 setter 的计算属性就是只读计算属性。
只读计算属性总是返回一个值,可以通过点(.)运算符访问,但不能设置新的值。
class film {
var head = ""
var duration = 0.0
var metaInfo: [String:String] {
return [
"head": self.head,
"duration":"\(self.duration)"
]
}
}
var movie = film()
movie.head = "Swift 属性"
movie.duration = 3.09
print(movie.metaInfo["head"]!)
print(movie.metaInfo["duration"]!)
属性观察器
属性观察器监控和响应属性值的变化,每次属性被设置值的时候都会调用属性观察器,甚至新的值和现在的值相同的时候也不例外。
可以为属性添加如下的一个或全部观察器:
willSet在设置新的值之前调用
didSet在新的值被设置之后立即调用
willSet和didSet观察器在属性初始化过程中不会被调用
class Samplepgm {
var counter: Int = 0{
willSet(newTotal){
print("计数器: \(newTotal)")
}
didSet{
if counter > oldValue {
print("新增数 \(counter - oldValue)")
}
}
}
}
let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800
输出:
计数器: 100
新增数 100
计数器: 800
新增数 700
全局变量
计算属性和属性观察器所描述的模式也可以用于全局变量和局部变量。
类型属性是作为类型定义的一部分写在类型最外层的花括号({})内。
使用关键字 static 来定义值类型的类型属性,关键字 class 来为类定义类型属性。
struct Structname {
static var storedTypeProperty = " "
static var computedTypeProperty: Int {
// 这里返回一个 Int 值
}
}
enum Enumname {
static var storedTypeProperty = " "
static var computedTypeProperty: Int {
// 这里返回一个 Int 值
}
}
class Classname {
class var computedTypeProperty: Int {
// 这里返回一个 Int 值
}
}
27.方法
import Cocoa
class Counter {
var count = 0
func increment() {
count += 1
}
func incrementBy(amount: Int) {
count += amount
}
func reset() {
count = 0
}
}
// 初始计数值是0
let counter = Counter()
// 计数值现在是1
counter.increment()
// 计数值现在是6
counter.incrementBy(amount: 5)
print(counter.count)
// 计数值现在是0
counter.reset()
print(counter.count)
在实例方法中修改值类型
Swift 语言中结构体和枚举是值类型。一般情况下,值类型的属性不能在它的实例方法中被修改。
但是,如果你确实需要在某个具体的方法中修改结构体或者枚举的属性,你可以选择变异(mutating)这个方法,然后方法就可从方法内部改变它的属性;并且它做的任何改变在方法结束时还会保留在原始结构中。
方法还可以给它隐含的self属性赋值一个全新的实例,这个新实例在方法结束后将替换原来的实例。
struct area {
var length = 1
var breadth = 1
func area() -> Int {
return length * breadth
}
mutating func scaleBy(res: Int) {
length *= res
breadth *= res
print(length)
print(breadth)
}
}
var val = area(length: 3, breadth: 5)
val.scaleBy(res: 3)
val.scaleBy(res: 30)
val.scaleBy(res: 300)
在可变方法中给self赋值:可变方法能够赋给隐含属性self一个全新的实例。
struct area {
var length = 1
var breadth = 1
func area() -> Int {
return length * breadth
}
mutating func scaleBy(res: Int) {
self.length *= res
self.breadth *= res
print(length)
print(breadth)
}
}
var val = area(length: 3, breadth: 5)
val.scaleBy(res: 13)
类型方法
实例方法是被类型的某个实例调用的方法,你也可以定义类型本身调用的方法,这种方法就叫做类型方法。
声明结构体和枚举的类型方法,在方法的func关键字之前加上关键字static。类可能会用关键字class来允许子类重写父类的实现方法。
类型方法和实例方法一样用点号(.)语法调用。
class Math
{
class func abs(number: Int) -> Int
{
if number < 0
{
return (-number)
}
else
{
return number
}
}
}
struct absno
{
static func abs(number: Int) -> Int
{
if number < 0
{
return (-number)
}
else
{
return number
}
}
}
let no = Math.abs(number: -35)
let num = absno.abs(number: -5)
print(no)
print(num)
28.下标脚本
下标脚本 可以定义在类(Class)、结构体(structure)和枚举(enumeration)这些目标中,可以认为是访问对象、集合或序列的快捷方式,不需要再调用实例的特定的赋值和访问方法。
对于同一个目标可以定义多个下标脚本,通过索引值类型的不同来进行重载,而且索引值的个数可以是多个。
语法:
下标脚本允许你通过在实例后面的方括号中传入一个或者多个的索引值来对实例进行访问和赋值。
语法类似于实例方法和计算型属性的混合。
与定义实例方法类似,定义下标脚本使用subscript关键字,显式声明入参(一个或多个)和返回类型。
与实例方法不同的是下标脚本可以设定为读写或只读。这种方式又有点像计算型属性的getter和setter:
struct subexample {
let decrementer: Int
subscript(index: Int) -> Int {
return decrementer / index
}
}
let division = subexample(decrementer: 100)
print("100 除以 9 等于 \(division[9])") //11
print("100 除以 2 等于 \(division[2])") //50
print("100 除以 3 等于 \(division[3])") //33
print("100 除以 5 等于 \(division[5])") //20
print("100 除以 7 等于 \(division[7])") //14
class daysofaweek {
private var days = ["Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "saturday"]
subscript(index: Int) -> String {
get {
return days[index] // 声明下标脚本的值
}
set(newValue) {
self.days[index] = newValue // 执行赋值操作
}
}
}
var p = daysofaweek()
print(p[0]) //Sunday
print(p[1]) //Monday
print(p[2]) //Tuesday
print(p[3]) //Wednesday
通常下标脚本是用来访问集合(collection),列表(list)或序列(sequence)中元素的快捷方式。
你可以在你自己特定的类或结构体中自由的实现下标脚本来提供合适的功能。
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2
print(numberOfLegs) //["ant": 6, "bird": 2, "cat": 4, "spider": 8]
下标脚本选项
下标脚本允许任意数量的入参索引,并且每个入参类型也没有限制。
下标脚本的返回值也可以是任何类型。
下标脚本可以使用变量参数和可变参数。
一个类或结构体可以根据自身需要提供多个下标脚本实现,在定义下标脚本时通过传入参数的类型进行区分,使用下标脚本时会自动匹配合适的下标脚本实现运行,这就是下标脚本的重载。
struct Matrix {
let rows: Int, columns: Int
var print: [Double]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
print = Array(repeating: 0.0, count: rows * columns)
}
subscript(row: Int, column: Int) -> Double {
get {
return print[(row * columns) + column]
}
set {
print[(row * columns) + column] = newValue
}
}
}
// 创建了一个新的 3 行 3 列的Matrix实例
var mat = Matrix(rows: 3, columns: 3)
// 通过下标脚本设置值
mat[0,0] = 1.0
mat[0,1] = 2.0
mat[1,0] = 3.0
mat[1,1] = 5.0
// 通过下标脚本获取值
print("\(mat[0,0])") //1.0
print("\(mat[0,1])") //2.0
print("\(mat[1,0])") //3.0
print("\(mat[1,1])") //5.0