Swift基礎(chǔ)-函數(shù)

  • 函數(shù)相當(dāng)于OC中的方法
  • 函數(shù)的格式如下
func 函數(shù)名(參數(shù)列表) -> 返回值類型 {
    代碼塊
    return 返回值
}
  • func是關(guān)鍵字,多個(gè)參數(shù)列表之間可以用逗號(,)分隔,也可以沒有參數(shù)
  • 使用箭頭“->”指向返回值類型
  • 如果函數(shù)沒有返回值,返回值為Void.并且“->返回值類型”部分可以省略

常見的函數(shù)類型

// 1.沒有參數(shù),沒用返回值
func about() -> Void {
    print("iphone6s plus")
}
// 調(diào)用函數(shù)
about()

// 簡單寫法
// 如果沒用返回值,Void可以寫成()
func about1() -> () {
    print("iphone6s plus")
}
// 如果沒有返回值,后面的內(nèi)容可以都不寫
func about2() {
    print("iphone6s plus")
}

about2()

// 2.有參數(shù),沒用返回值
func callPhone(phoneNum : String) {
    print("打電話給\(phoneNum)")
}
callPhone("+86 110")

// 3.沒用參數(shù),有返回值
func readMessage() -> String {
    return "吃飯了嗎?"
}
var str = readMessage()
print(str)

// 4.有參數(shù),有返回值
func sum(num1 : Int, num2 : Int) -> Int {
    return num1 + num2
}
var result = sum(20, num2: 30)
print(result)

// 5.有多個(gè)返回值的函數(shù)
let nums = [1, 3, 4, 8, 22, 23]
func getNumCount(nums : [Int]) -> (oddCount : Int, evenCount : Int) {
    var oddCount = 0
    var evenCount = 0
    for num in nums {
        if num % 2 == 0 {
            oddCount++
        } else {
            evenCount++
        }
    }
    return (oddCount, evenCount)
}

let result = getNumCount(nums)
result.oddCount
result.evenCount

函數(shù)的使用注意

  • 注意一: 外部參數(shù)和內(nèi)部參數(shù)
    • 在函數(shù)內(nèi)部可以看到的參數(shù),就是內(nèi)部參數(shù)
      • Swift2.0以前, 默認(rèn)情況下的參數(shù)都是內(nèi)部參數(shù)
      • Swift2.0開始, 默認(rèn)將第二個(gè)參數(shù)名稱作為外部參數(shù)
    • 在函數(shù)外面可以看到的參數(shù),就是外部參數(shù)
    • 默認(rèn)情況下,從第二個(gè)參數(shù)開始,參數(shù)名稱既是內(nèi)部參數(shù)也是外部參數(shù)
    • 如果第一個(gè)參數(shù)也想要有外部參數(shù),可以設(shè)置標(biāo)簽:在變量名前加標(biāo)簽即可
    • 如果不想要外部參數(shù),可以在參數(shù)名稱前加_
      // Swift2.0之前, 默認(rèn)是不會將第二個(gè)參數(shù)開始的參數(shù)名稱作為外部參數(shù)的, 必須自己手動(dòng)指定
// num1和a是外部參數(shù)的名稱
func ride(num1 num1 : Int, a num2 : Int, b num3 : Int) -> Int {
    return num1 * num2 * num3
}
var result1 = ride(num1: 20, a: 4, b: 5)

// 方法的重載:方法名稱相同,但是參數(shù)不同,可以稱之為方法的重載(了解)
func ride(num1: Int, _ num2 :Int) -> Int {
    return num1 * num2
}

var result2 = ride(20, 20)
  • 注意二: 默認(rèn)參數(shù)
    • 某些情況,如果沒有傳入具體的參數(shù),可以使用默認(rèn)參數(shù)
    • 當(dāng)默認(rèn)值被定義后实抡,調(diào)用這個(gè)函數(shù)時(shí)可以忽略這個(gè)參數(shù)
    • 其它語言的默認(rèn)參數(shù)必須寫在最后面, Swift可以寫在任意位置
    • 建議將帶有默認(rèn)值的參數(shù)放在函數(shù)參數(shù)列表的最后姐帚。這樣可以保證在函數(shù)調(diào)用時(shí)恩沛,非默認(rèn)參數(shù)的順序是一致的,同時(shí)使得相同的函數(shù)在不同情況下調(diào)用時(shí)顯得更為清晰胚股。
// 卡布奇諾是默認(rèn)參數(shù)
func makecoffee(type :String = "卡布奇諾") -> String {
    return "制作一杯\(type)咖啡。"
}

let coffee1 = makecoffee("拿鐵") // coffee1 = 拿鐵
let coffee2 = makecoffee() // coffee2 = 卡布奇諾
  • 注意三: 可變參數(shù)
    • swift中函數(shù)的參數(shù)個(gè)數(shù)可以變化裙秋,它可以接受不確定數(shù)量的輸入類型參數(shù)
    • 它們必須具有相同的類型
    • 我們可以通過在參數(shù)類型名后面加入(...)的方式來指示這是可變參數(shù)
func sum(numbers:Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total
}

sum(100.0, 20, 30)
sum(30, 80)
  • 注意四: 引用類型(指針的傳遞)
    • 默認(rèn)情況下,函數(shù)的參數(shù)是值傳遞.如果想改變外面的變量,則需要傳遞變量的地址
    • 必須是變量,因?yàn)樾枰趦?nèi)部改變其值
    • Swift提供的inout關(guān)鍵字就可以實(shí)現(xiàn)
    • 對比下列兩個(gè)函數(shù)
// 函數(shù)一:值傳遞
func swap(var a : Int, var b : Int) {
    let temp = a;
    a = b;
    b = temp

    print("a:\(a), b:\(b)")
}

var a = 10
var b = 20
swap(a, b: b)
print("a:\(a), b:\(b)")

// 函數(shù)二:指針的傳遞
func swap1(inout a : Int, inout b : Int) {
    let temp = a
    a = b
    b = temp

    print("a:\(a), b:\(b)")
}

swap1(&a, b: &b)
print("a:\(a), b:\(b)")
  • 函數(shù)的嵌套使用
    • swift中函數(shù)可以嵌套使用
    • 即函數(shù)中包含函數(shù),但是不推薦該寫法
// 函數(shù)的嵌套
let value = 55
func test() {
    func demo() {
        print("demo \(value)")
    }

    print("test")
    demo()
}

demo() // 錯(cuò)誤
test() // 執(zhí)行函數(shù)會先打印'test',再打印'demo'

函數(shù)的類型

  • 函數(shù)類型的概念
    • 每個(gè)函數(shù)都有屬于自己的類型琅拌,由函數(shù)的參數(shù)類型和返回類型組成
      • 這個(gè)例子中定義了兩個(gè)簡單的數(shù)學(xué)函數(shù):addTwoInts 和 multiplyTwoInts
      • 這兩個(gè)函數(shù)都傳入兩個(gè) Int 類型, 返回一個(gè)合適的Int值
      • 這兩個(gè)函數(shù)的類型是 (Int, Int) -> Int
// 定義兩個(gè)函數(shù)
func addTwoInts(a : Int, b : Int) -> Int {
    return a + b
}

func multiplyTwoInt(a : Int, b : Int) -> Int {
    return a * b
}
  • 抽取兩個(gè)函數(shù)的類型,并且使用
// 定義函數(shù)的類型
var mathFunction : (Int, Int) -> Int = addTwoInts

// 使用函數(shù)的名稱
mathFunction(10, 20)

// 給函數(shù)的標(biāo)識符賦值其他值
mathFunction = multiplyTwoInt

// 使用函數(shù)的名稱
mathFunction(10, 20)
  • 函數(shù)作為方法的參數(shù)
// 將函數(shù)的類型作為方法的參數(shù)
func printResult(a : Int, b : Int, calculateMethod : (Int, Int) -> Int) {
    print(calculateMethod(a, b))
}

printResult(10, b: 20, calculateMethod: addTwoInts)
printResult(10, b: 20, calculateMethod: multiplyTwoInt)
  • 函數(shù)作為方法的返回值
// 1.定義兩個(gè)函數(shù)
func stepForward(num : Int) -> Int {
    return num + 1
}

func stepBackward(num : Int) -> Int {
    return num - 1
}

// 2.定義一個(gè)變量,希望該變量經(jīng)過計(jì)算得到0
var num = -4

// 3.定義獲取哪一個(gè)函數(shù)
func getOprationMethod(num : Int) -> (Int) -> Int {
    return num <= 0 ? stepForward : stepBackward
}

// 4.for循環(huán)進(jìn)行操作
while num != 0 {
    let oprationMethod = getOprationMethod(num)
    num = oprationMethod(num)
    print(num)
}

常量參數(shù)和變量參數(shù)(Constant and Variable Parameters)

  • 函數(shù)參數(shù)默認(rèn)是常量, 在函數(shù)內(nèi)部不能修改
  • 如果想在函數(shù)中修改參數(shù), 必須在參數(shù)前加上var
  • 注意
    • 對變量參數(shù)所進(jìn)行的修改在函數(shù)調(diào)用結(jié)束后便消失了摘刑,并且對于函數(shù)體外是不可見的进宝。變量參數(shù)僅僅存在于函數(shù)調(diào)用的生命周期中
func sum4(let i: Int, let j: Int) {
    print(i + j)
}
sum4(10, j: 20)


var num1 = 10
var num2 = 20
//func swap(value1: Int, value2: Int){
//    let temp = value1
//    value1 = value2
//    value2 = temp
//}

// 注意: 操作的是局部變量, 對實(shí)參沒有影響
func swap1(var value1: Int, var value2: Int){
    print("交互前: value1 = \(value1), value2 = \(value2)")
    let temp = value1
    value1 = value2
    value2 = temp
    print("交互后: value1 = \(value1), value2 = \(value2)")
}

swap1(num1, value2: num2)
print(num1)
print(num2)

輸入輸出參數(shù)(In-Out Parameters)

  • 變量參數(shù),正如上面所述枷恕,僅僅能在函數(shù)體內(nèi)被更改党晋。如果你想要一個(gè)函數(shù)可以修改參數(shù)的值,并且想要在這些修改在函數(shù)調(diào)用結(jié)束后仍然存在徐块,那么就應(yīng)該把這個(gè)參數(shù)定義為輸入輸出參數(shù)(In-Out Parameters)

  • 定義一個(gè)輸入輸出參數(shù)時(shí)未玻,在參數(shù)定義前加 inout 關(guān)鍵字

  • 注意

    • 輸入輸出參數(shù)不能有默認(rèn)值,而且可變參數(shù)不能用 inout 標(biāo)記胡控。如果你用 inout 標(biāo)記一個(gè)參數(shù)扳剿,這個(gè)參數(shù)不能被 var 或者 let 標(biāo)記。
func swap2(inout value1: Int, inout value2: Int){
    print("交互前: value1 = \(value1), value2 = \(value2)")
    let temp = value1
    value1 = value2
    value2 = temp
    print("交互后: value1 = \(value1), value2 = \(value2)")
}
swap2(&num1, value2: &num2)
print(num1)
print(num2)

可變參數(shù)(Variadic Parameters)

  • 一個(gè)可變參數(shù)可以接收零個(gè)或多個(gè)值
  • 如果沒有變參函數(shù) , 并且函數(shù)的參數(shù)個(gè)數(shù)又不確定那么只能寫多個(gè)方法或者用將函數(shù)參數(shù)改為集合
  • 格式 func method(parameter: Int...){}
  • 可變參數(shù)在函數(shù)中可以當(dāng)做一個(gè)數(shù)組

注意

  • 一個(gè)函數(shù)最多只能有一個(gè)可變參數(shù)
  • 變參只能是同種類型的數(shù)據(jù)
  • 變參必須指定數(shù)據(jù)類型
  • 如果函數(shù)有一個(gè)或多個(gè)帶默認(rèn)值的參數(shù)昼激,而且還有一個(gè)可變參數(shù)舞终,那么把可變參數(shù)放在參數(shù)表的最后
func sum5(numbers: Int...) {
//    print(numbers)
    var sum = 0
    for number in numbers {
        sum += number
    }
    print(sum)
}
sum5(1, 2, 3)

// 不推薦寫法, 和默認(rèn)值一樣, 變參最好寫在最后
func sum6(numbers: Int..., var sum: Int) {
    //    print(numbers)
    for number in numbers {
        sum += number
    }
    print(sum)
}
sum6(1, 2, 3, sum: 0)

// 推薦寫法
func sum7(var sum: Int = 100, numbers: Int...) {
    //    print(numbers)
    for number in numbers {
        sum += number
    }
    print(sum)
}
sum7(numbers: 1, 2, 3)

// 一個(gè)函數(shù)中只能有一個(gè)變參
//func sum8(numbers: Int..., values: Int...){
//    print(numbers)
//    print(values)
//}


// 有參數(shù)有返回值
func sum8(i: Int, j: Int) -> Int {
    return i + j
}
let result = sum8(10, j: 20)
print(result)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末轻庆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子敛劝,更是在濱河造成了極大的恐慌余爆,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夸盟,死亡現(xiàn)場離奇詭異蛾方,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)上陕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門桩砰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人释簿,你說我怎么就攤上這事亚隅。” “怎么了庶溶?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵煮纵,是天一觀的道長。 經(jīng)常有香客問我偏螺,道長行疏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任套像,我火速辦了婚禮酿联,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘夺巩。我一直安慰自己贞让,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布柳譬。 她就那樣靜靜地躺著震桶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪征绎。 梳的紋絲不亂的頭發(fā)上蹲姐,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音人柿,去河邊找鬼柴墩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛凫岖,可吹牛的內(nèi)容都是我干的江咳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼哥放,長吁一口氣:“原來是場噩夢啊……” “哼歼指!你這毒婦竟也來了爹土?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤踩身,失蹤者是張志新(化名)和其女友劉穎胀茵,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挟阻,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡琼娘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了附鸽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脱拼。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖坷备,靈堂內(nèi)的尸體忽然破棺而出熄浓,到底是詐尸還是另有隱情,我是刑警寧澤省撑,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布赌蔑,位于F島的核電站,受9級特大地震影響丁侄,放射性物質(zhì)發(fā)生泄漏惯雳。R本人自食惡果不足惜朝巫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一鸿摇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧劈猿,春花似錦拙吉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仗颈,卻和暖如春佛舱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挨决。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工请祖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脖祈。 一個(gè)月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓肆捕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親盖高。 傳聞我的和親對象是個(gè)殘疾皇子慎陵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容