函数在任何语言中都是存在的,Swift中函数更加灵活。
func pi() -> Double {
return 3.14
}
print(pi()) // 输出:3.14
func sum(v1: Int, v2: Int) -> Int {
return v1 + v2
}
print(sum(v1: 10, v2: 20)) // 输出:30
func hello() -> Void {
print("hello")
}
func hello() -> () {
print("hello")
}
func hello() {
print("hello")
}
hello() // 输出:hello
func sum(v1: Int, v2: Int) -> Int {
v1 + v2
}
print(sum(v1: 10, v2: 10)) // 输出:20
func calculate(v1: Int, v2: Int) -> (sum: Int, difference: Int, average: Int) {
let sum = v1 + v2
return (sum, v1 - v2, sum >> 1)
}
let result = calculate(v1: 10, v2: 20)
print(result.sum, result.difference, result.average) // 输出:30 -10 15
函数可以修改参数标签:
// at是外面调用的,time是函数内部使用的
func goToWord(at time: String) {
print("time is \(time)")
}
goToWord(at: "8:00")
可以使用下划线_
省略参数标签:
func sum(_ v1: Int, _ v2: Int) -> Int { v1 + v2}
sum(10, 20)
func check(name: String = "nobody", age: Int, job: String = "none") {
print("name=\(name), age=\(age), job=\(job)")
}
check(age: 10)
check(name: "Jack", age: 20, job: "Programmer")
check(name: "Eve", age: 18)
check(age: 10, job: "Superman")
/*
输出:
name=nobody, age=10, job=none
name=Jack, age=20, job=Programmer
name=Eve, age=18, job=none
name=nobody, age=10, job=Superman
*/
func sum(_ numbers: Int...) -> Int {
var total = 0
for number in numbers {
total += number
}
return total
}
let result = sum(10, 20, 30, 40)
print(result) // 输出:100
func test(_ numbers: Int..., string: String, _ other: String) {
}
test(10, 20, 30, string: "idbeny", "1024星球")
inout
必须和&
配合使用inout
inout
参数不能有默认值inout
参数只能传入可以被多次赋值的如下修改会报错(因为形参是用let修饰的)
使用inout
和&
var number = 10
func add(_ num: inout Int) {
num = 20
}
add(&number)
print(number) // 输出:20
通过这种方式也可以交换两个变量的值(其实官方有提供交换函数swap
)
// 方法一(使用临时变量)
func swapValues(_ v1: inout Int, _ v2: inout Int) {
let temp = v1
v1 = v2
v2 = temp
}
var num1 = 10
var num2 = 20
swapValues(&num1, &num2)
print("num1=\(num1), num2=\(num2)") // 输出:num1=20, num2=10
// 方法二(使用元组)
var num3 = 30
var num4 = 40
func swapValues1(_ v1: inout Int, _ v2: inout Int) {
(v1, v2) = (v2, v1)
}
swap(&num3, &num4)
print("num3=\(num3), num4=\(num4)") // 输出:num3=40, num4=30
// 方法三(系统提供的swap函数)
var num5 = 50
var num6 = 60
swap(&num5, &num6)
print("num5=\(num5), num6=\(num6)") // 输出:num5=60, num6=50
官网介绍:https://swift.org/documentatior/api-design-guidelines
光标放到对应函数名称上,按下Option
即可查看函数相关描述文档
Command + Option + /
默认的文档注释
/// <#Description#>
/// - Parameters:
/// - v1: <#v1 description#>
/// - v2: <#v2 description#>
/// - Returns: <#description#>
func sum(v1: Int, v2: Int) -> Int { v1 + v2}
更详细的文档注释(概述和详述一定要隔开,否则会默认为详述)
/// 将2个整数相加【概述】
///
/// 将2个整数相加【详细的描述】
/// - Parameters:
/// - v1: 第一个参数
/// - v2: 第二个参数
/// - Returns: 2个参数的和
/// - Note:传入2个整数【批注】
func sum(v1: Int, v2: Int) -> Int { v1 + v2}
效果
以下函数都构成了函数重载,都是可以正常调用的,且函数没有冲突:
// 参照
func sum(v1: Int, v2: Int) {
v1 + v2
}
// 参数个数不同
func sum(v1: Int, v2: Int, v3: Int) {
v1 + v2 + v3
}
// 参数类型不同
func sum(v1: Int, v2: Double) {
Double(v1) + v2
}
// 参数标签不同(忽略标签)
func sum(_ v1: Int, _ v2: Int) {
v1 + v2
}
// 参数标签不同(标签名不同)
func sum(a: Int, b: Int) {
a + b
}
返回值类型与函数重载无关
默认参数值和函数重载一起使用产生二义性时,编译器不会报错(在C++中会报错)
func sum(v1: Int, v2: Int) -> Int {
v1 + v2
}
func sum(v1: Int, v2: Int, v3: Int = 30) -> Int {
v1 + v2 + v3
}
sum(v1: 10, v2: 20) // 输出:30
为什么是可能会报错?(下面代码可以正常执行,所以平时开发中也不建议这样写)
func sum(_ v1: Int, _ v2: Int) -> Int {
v1 + v2
}
func sum(_ numbers: Int...) -> Int {
var total = 0
for num in numbers {
total += num
}
return total
}
sum(10, 20) // 输出:30
每一个函数都是有类型的,函数类型由形式参数类型,返回值类型组成:
将函数定义在函数内部:
func foward(_ forward: Bool) -> (Int) -> Int {
func next(_ input: Int) -> Int {
input + 1
}
func previous(_ input: Int) -> Int {
input - 1
}
return forward ? next : previous
}
foward(true)(1) // 输出:2
foward(false)(2) // 输出:1
如果开启了编译器优化(Release模式默认开启),编译器会自动将某些函数变成内联函数:
内联函数的作用?
func test() {
print("test")
}
test()
test()
会替换为print("test")
。不是所有的内联函数都会被编译器展开函数体,那些函数不会被内联?
@inline:
永远不会被内联(即使开启了编译器优化)
@inline(never) func test() {
print("test")
}
开启编译器优化后,及时代码很长,也会被内联(递归调用、动态派发的函数除外):
@inline(__always) func test1() {
print("test")
}
@inline
。更多系列文章,请关注 微信公众号【1024星球】
原文:https://www.cnblogs.com/idbeny/p/swift-syntax-function.html