目录
一、开发环境
二、关于Swift
(一)Swift简介
(二)Swift特性
(三)结语
三、Swift基础语法
(一)编程准备
(二)Hello,world!
(三)简单值
1.变量与常量
2.类型
3.字符串
4.数组、字典、集合以及元组
4.可选类型Optional
(四)控制流
1.条件语句
2.循环语句
(五)函数和闭包
1.函数
2.嵌套函数
3.输入输出参数
4.可变参数
5.闭包
一、开发环境
- 编程语言: Swift (截至2021.09.20,最新版本是Swift5.5)
- 开发工具: Xcode编辑器 (可以在AppStore下载)
- 操作系统: MacOS (最好是Mojava 2018或者更高版本)
- 开发设备: iMac、MacBook等 (或者搭载了MacOS的虚拟机)
相关开发工具可在Swift.org - Download Swift上下载
二、关于Swift
(一)Swift简介
Swift 是苹果于2014年在WWDC上发布的一门新的编程语言,可以用于编写 iOS、OS X 和 watchOS应用程序。Swift 结合了C和Objective-C的优点并且不受C兼容性的限制。
(二)Swift特性
- 安全性 Swift提供了多种安全措施,比如值使用前初始化、自动内存管理等。
- 快速性 Swift使用LLVM作为它的编译器框架,运行速度很快。
- 表现力 Swift将强大的类型推断和模式匹配与现代、轻量级的语法相结合,允许以清晰简洁的方式表达复杂的想法。因此代码不仅更易于编写,而且更易于阅读和维护。
- 兼容性 Swift可以兼容Objective-C的代码,同时Swift也继承了C语言以及Objective-C的特性,克服了C语言的兼容性问题。
参考资料:Swift.org - About Swift
此外,Swift还具有以下特点:
- Swif中并没有加入宏系统,其协议和扩展都源自Objective-C;
- Swif采用var声明变量和let声明常量;
- Swif没有显示指针,而是像C#语言一样,依赖于值类型/引用类型;
- Swif支持本地类型推断、整理数值类型,但不支持隐式强制转换,所有的代码需要转化为显式类型。
以上内容参考了Rust创始人Graydon Hoare对Swift的部分看法
(三)结语
Swift是一门极具现代风格的编程语言,如果你想学习Swift,最好有一定的编程基础,并且对面向对象的编程思想有一定的了解。
笔者对于Swift印象最深的点有两个——
一是Swift强大的字符集——Swift允许变量名、常量名等标识符使用中文名称,也可以包含表情等其他字符。二是Swift支持代码预览,是一边写代码一边进行编译的,而不必等到整个程序写完了才编译代码,可以帮助我们及时发现一些错误。(如图)
关于Swift的学习,可以参考一些书籍和视频教程,但笔者以为最好的学习方式是查看其官方文档——Swift官方社区:Swift.org - Welcome to Swift.org
三、Swift基础语法
(一)编程准备
1.打开Xcode之后,你将看到下面的页面
2.左上角选择File->New->Playground
3.选择Blank,双击或点击Next
4.输入文件名称,选择文件路径
然后就可以开始你的Swift之旅了!
(二)Hello,world!
一门语言最快的入门方式是编写一个Hello,world!程序,在Swift中这只需要一条语句完成
print("Hello, world!")
点击红色箭头标记的图标就可以运行了。第一次运行可能会比较慢,耐心等待就好
(三)简单值
1.变量与常量
常量与变量必须在使用前声明,Swift使用var声明变量,使用let声明变量。
var aVariable = 65 //变量声明
aVariable = 53
let aCOnstant= 36 //常量声明
注意,在上述例子中我们没有标明常量与变量的类型,但这不意味着它们没有类型,只是我们选择以缺省的方式让编译器去推断它们的类型。在上述例子中,变量aVariable和常量aConstant都是整数类型,因为它们的初始值是整数类型。
Swift中变量与常量都是具有类型的,而且它们的类型必须与要分配的值的类型相同。只是编译器允许在初始化变量或常量时不必总是显示地编写它们的类型,而是提供一个值让编译器去推断其类型。
1.与C、C++等编程语言要求语句以“;”结尾不同,Swift不要求在每条语句的结尾编写“;”(如果添加了“;”编译器也不会报错)。但是,如果要在一行中编写多个单独的语句,则需要分号
2.与C语言类似,Swift的单行注释以“//”开头,多行注释使用“/* ...*/”。但是Swift允许多行注释嵌套,例如:
/* This is the start of the first multiline comment./* This is the second, nested multiline comment. */
This is the end of the first multiline comment. */
如果要在一行中声明多个常量或多个变量,需要使用“,”分隔
var x = 0.0, y = 0.0, z = 0.0
2.类型
上面我们说了可以省略变量/常量的类型,让编译器去推断。但是我们也可以使用类型注释指定变量与常量的类型,使用方法如下
var 标识符: 类型 = 初始值
let 标识符: 类型 = 初始值
var aVariable: Int = 65 //Int型变量声明
aVariable = 53
let aConstant: Float= 36 //Float型常量声明
1.Swift的基本数据类型包括Int、Float、Double、Bool(取值范围:true/false)、Character、String等等。
2.Swift要求二元运算符(+、-、*、/、%等)两端空格。此外,考虑到代码风格的统一,赋值号两端最好也要有空格。
3.字符串
Swift定义了字符串类型为String
let label: String = "The width is " //可以写成let label = "The width is "
let width = 94
let widthLabel = label + String(width)
注意,Swift没有隐式转换。如果需要将值转换为不同的类型,必须使用显示转换。
如果需要在字符串中包含值,可以在字符串中采用\(表达式)的写法,将括号中表达式的值转义,例如:
let width = 94
let widthLabel = "The width is \(width)"
前面我们提到Swift的语句不以“;”结尾,如果一个字符串占用多行,需要使用三个双引号"""将字符串包围起来。注意删除每个引用行开头的缩进,例如:
let quotation = """
I said "I have \(apples) apples."
And then I said "I have \(apples + oranges) pieces of fruit."
"""
4.数组、字典、集合以及元组
数组是有序的元素序列,是包含相同元素的集合。例如:
//创建数组:
var shoppingList = ["catfish", "water", "tulips"]
/*var shoppingList: [String] = ["catfish", "water", "tulips"]*/
shoppingList[1] = "bottle of water"
我们可以使用append往数组中添加元素,数组会自动增长,例如:
shoppingList.append("blue paint")
字典可以理解为键值对(key-value),可以通过某个特定的词语(键),从而找到它的定义(值)。
//创建字典:
var occupatiOns= ["Malcolm": "Captain","Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"
如果要创建一个空数组或空字典,需要采用下面的写法:
let shoppingList: [String] = []
let occupations: [String: Float] = [:]
集合是一组无序不重复的相同类型元素构成的整体,与数学中集合的概念类似。
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
元组是可以由不同类型元素构成的集合,例如:
var aturple = (18 , 175 , 60.5 , "healthy" , true)
4.可选类型Optional
可选类型Optional是Swift特有的数据类型,可选类型的值可能是某个类型的值也可能是nil(表示没有值)。
可选类型的定义,在类型后面加“?”:
var str: String?
可选类型在使用的时候必须要拆包,下面提供Optional的三种使用方式:
1) 隐式拆包
在定义可选类型的时候使用“!”,后面使该可选类型的时候不需要强制解包
let x : String! = "Hello"
let y = x
2) 强制解包
使用可选类型变量时,在其后加“!”,如果使用不合法编译器会报错。
let x : String? = "hello"
let y = x!
3) If-let可选绑定
使用 if let临时常量 = 可选类型 来判断可选类型是否包含值,如果包含就把值赋给临时常量,否则(可选类型为nil时)if语句判断为假。
var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {greeting = "Hello, \(name)"
}
(四)控制流
1.条件语句
if分支语句:
if score > 50 {teamScore += 3
} else {teamScore += 1
}
switch分支语句:
var vegetable = "red pepper"
switch vegetable {
case "celery":print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":print("That would make a good tea sandwich.")
case let x where x.hasSuffix("pepper"):print("Is it a spicy \(x)?")
default:print("Everything tastes good in soup.")
}
// Prints "Is it a spicy red pepper?"
2.循环语句
for循环:
var total = 0
for i in 0..<4 {total += i
}
print(total)
// Prints "6"
//0..<表示半闭合区间[0,4),0...4表示闭合区间[0,4]
如果不需要区间序列内每项的值,可以用下划线“_”替代变量名:
let base = 3 ,power = 10
var answer = 1
for _ in 1...power {
answer *= base
}
取数组里的值:
let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {if score > 50 {teamScore += 3} else {teamScore += 1}
}
print(teamScore)
// Prints "11"
取字典里的值:
let interestingNumbers = ["Prime": [2, 3, 5, 7, 11, 13],"Fibonacci": [1, 1, 2, 3, 5, 8],"Square": [1, 4, 9, 16, 25],
]
var largest = 0
for (_, numbers) in interestingNumbers {for number in numbers {if number > largest {largest = number}}
}
print(largest)
// Prints "25"
while循环(当型循环):
var n = 2
while n <100 {n *= 2
}
print(n)
// Prints "128"
while-repeat循环(直到型循环:循环体至少执行一次):
var m = 2
repeat {m *= 2
} while m <100
print(m)
// Prints "128"
(五)函数和闭包
1.函数
函数声明的格式:
func 函数名(参数名称1: 类型, 参数名称2: 类型, ......) -> 返回类型 {}
func greet(person: String, day: String) -> String {return "Hello \(person), today is \(day)."
}
greet(person: "Bob", day: "Tuesday")
//person和day是参数标签,同时也是参数名称
默认情况下,函数使用其参数名称作为其参数的标签。如果参数标签与参数名称不同,需要在定义函数时把自定义参数标签写入参数名称之前,或写入_表示(函数调用时)不使用参数标签。
func greet(_ person: String, on day: String) -> String {return "Hello \(person), today is \(day)."
}
greet("John", on: "Wednesday")
如果函数有多个返回值,可以把元组作为返回值:
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {var min = scores[0]var max = scores[0]var sum = 0for score in scores {if score > max {max = score} else if score }
let statistics = calculateStatistics(scores: [5, 3, 100, 3, 9])
print(statistics.sum)
// Prints "120"
print(statistics.2)
// Prints "120"
2.嵌套函数
Swift的函数可以嵌套定义,嵌套函数可以访问在外部函数声明的变量。我们可以使用嵌套函数在较长或复杂的函数中组织代码。
func returnFifteen() -> Int {var y = 10func add() {y += 5}add()return y
}
returnFifteen()
一个函数的返回值可以是另一个函数:
func makeIncrementer() -> ((Int) -> Int) {func addOne(number: Int) -> Int {return 1 + number}return addOne
}
var increment = makeIncrementer()
increment(7)
一个函数的参数可以是另一个函数:
func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {for item in list {if condition(item) {return true}}return false
}
func lessThanTen(number: Int) -> Bool {return number <10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(list: numbers, condition: lessThanTen)
3.输入输出参数
一般情况下不允许修改函数参数的值,试图在函数体中更改参数值将编译错误。
如果要修改参数的值,需要在函数定义时,使用inout关键字;在函数调用时,参数名前加 “&”
func swap(first a : inout Int, second b : inout Int)
{ let temp = a a = b b = temp
}
var x = 10,y = 20
swap (first: &x, second: &y)
print(x,y)
4.可变参数
可变参数可以接受0个或多个值,需要在函数定义参数时类型的后面加“...”
func arithmeticMean(_ numbers: Double...) -> Double { var total: Double = 0 for number in numbers { total += number } return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0
arithmeticMean(3, 8.25, 18.75)
// returns 10.0
5.闭包
函数实际上是闭包的一种特殊情况:可以稍后调用的代码块。
闭包是自包含的功能块,可以在代码中传递和使用。全局和嵌套函数实际上也是特殊的闭包,闭包采取如下三种形式之一:
- 全局函数是一个有名字但不会捕获任何值的闭包;
- 嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包;
- 闭包表达式是一个利用轻量级语法所写的可以捕获其上下文中变量或常量值的没有名字的闭包。
闭包表达式的格式:
{(参数) ->返回类型 in
声明
}
numbers.map({ (number: Int) -> Int inlet result = 3 * numberreturn result
})
01 | Swift基础语法(下)