閱讀95 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Swift學習之十三:函數(Functions)

/*
  函數(Function)
  函數是為執行特定功能的自包含的代碼塊。函數需要給定一個特定標識符(名字),然後當需要的時候,
  就調用此函數來執行功能。
*/
// 函數的定義與調用
// 定義函數時,使用關鍵字func,返回值類型通過->指明,如下:
// 函數名:sayHello,
// 參數列表中隻有一個參數,叫personName,參數類型是String
// 函數返回值類型:String
func sayHello(personName: String) -> String {
  let greeting = "Hello, " + personName + "!"
  return greeting
} 

// 函數調用
println(sayHello("Anna")) // prints "Hello, Anna"
println(sayHello("Brian")) // prints "Hello, Brian"

// 簡化函數體
func sayHelloAgain(personName: String) -> String {
  return "Hello, " + personName + "!"
}

println(sayHelloAgain("Anna"))


// 函數可以有多個參數
/*!
 * @brief 返回兩個值的差
 * @param start Int類型,範圍區間的起點
 * @param end Int類型,範圍區間的終點
 * @return 返回值為Int類型,表示終點-起點的值
 */
func halfOpenRangeLength(start: Int, end: Int) -> Int {
  return end - start
}
println(halfOpenRangeLength(1, 10)) // prints "9"


// 無參數函數
func sayHelloWorld() -> String {
  return "Hello, world"
}
println(sayHelloWorld())

// 無返回值的函數,其實這裏沒有指定返回值,也會返回一個特殊的值,Void
func sayGoodbye(personName: String) {
  println("Goodbye, \(personName)!")
}
sayGoodbye("David")

// 函數返回值是可以忽略的
func printAndCount(stringToPrint: String) -> Int {
  println(stringToPrint)
  return countElements(stringToPrint) // 計算字符串的長度
}

// 不帶返回值
func printWithoutCounting(stringToPrint: String) {
   printAndCount(stringToPrint)
}

printAndCount("Hello,world")
printWithoutCounting("hello, world")

/*
 * @brief 函數可以返回元組(多個值)
 * @param string 字符串
 * @return (vowels: Int, consonants: Int, others: Int)
 *         vowels:元音, consonants:輔音,others:其它字符
 */
 func count(string: String) ->(vowels: Int, consonants: Int, others: Int) {
    var vowels = 0
	var consonants = 0
	var others = 0
	for c in string {
	  switch String(c).lowercaseString {
	    case "a", "o", "e", "i", "u":
		  ++vowels
		case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n",
             "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
          ++consonants
        default:
          ++others		
	  }
	}
	return (vowels, consonants, others)
 }
 
 let total = count("some arbitrary string!")
 println("\(total.vowels) vowels and \(total.consonants) consonants")

 
// 外部參數名(External Parameter Names)
// 有時候使用外部參數名是很有用的,這直到提示的作用,就好像OC語法中的參數一樣,見名知意
func someFunction(externalParameterName localParameterName: Int) {
  // do something
}

// 看例子:
func join(lhsString: String, rhsString: String, joiner:String) -> String {
  return lhsString + joiner + rhsString
} 
// 這裏調用的時候,沒有外部參數名
join("hello", "world", ",") // prints "hello,world"

// 加上#號後,參數名與外部名相同,這是快捷方式
func join(#lhsString: String, #rhsString: String, #joiner:String) -> String {
  return lhsString + joiner + rhsString
} 
// 調用方式
join(lhsString: "hello", rhsString: "world", joiner: ",") // prints "hello,world"

// 可以不使用快捷方式
func join(lhsString: String, rhsString: String, withJoiner joiner: String) -> String {
  return lhsString + joiner + rhsString
}
join("hello", "world", withJoiner: ",")// prints "hello,world"

// 函數參數默認值
// 參數參數可以提供默認值,但是默認值隻能是參數列表的最後,也就是說
// 如果arg1提供默認值,後麵的都需要提供默認值。
func join(#originalString: String, #destinationString: String, #withJoiner: String = " ") -> String {
  return originalString + withJoiner + destinationString
}
join(originalString: "hello", destinationString: "world", withJoiner: "-") // prints "hello-world"
join(originalString: "hello", destinationString: "world") // prints "hello world"

// 如果提供了參數默認值,Swift會自動把這個參數名也作為外部參數名
// 這裏withJoiner相當於加上了#:#withJoiner
func join(lhsString: String, rhsString: String, withJoiner: String = " ") -> String {
  return lhsString + withJoiner + rhsString
}
join("hello", "world", withJoiner: "-")// // prints "hello-world"

// 可變參數
// 可變參數接受0個或者多個指定類型的值。可變參數使用...表示
// 函數最多隻能有一個可變參數,並且如果有可變參數,這個可變參數必須出現在參數列表的最後
// 如果參數列表中有一或多個參數提供默認值,且有可變參數,那麼可變參數也要放到所有最後一個
// 提供默認值的參數之後(先是默認值參數,才能到可變參數)
func arithmeticMean(numbers: Double...) -> Double {
  var total = 0.0
  for number in numbers {
    total += number
  }
  return total / Double(numbers.count)
}

arithmeticMean(1, 2, 3, ,4 5) // return 3.0
arithmeticMean(1, 2, 3) // return 2.0


// 常量和變量參數
// 在函數參數列表中,如果沒有指定參數是常量還是變量,那麼默認是let,即常量
// 這裏Str需要在函數體內修改,所以需要指定為變量類型,即用關鍵字var
func alignRight(var str: String, count: Int, pad: Character) -> String {
  let amountToPad = count - countElements(str)
  
  // 使用_表示忽略,因為這裏沒有使用到
  for _ in 1...amountToPad {
    str = pad + str
  }
  
  return str 
}

// 輸入/輸出參數
// 有時候,在函數體內修改了參數的值,如何能直接修改原始實參呢?就是使用In-Out參數
// 使用inout關鍵字聲明的變量就是了
// 下麵這種寫法,是不是很像C++中的傳引用?
func swap(inout lhs: Int, inout rhs: Int) {
  let tmp = lhs
  lhs = rhs
  rhs = tmp
}
// 如何調用呢?調用的調用,對應的實參前麵需要添加&這個符號
// 因為需要修改,所以一定是var類型的
var first = 3 
var second = 4
// 這種方式會修改實參的值
swap(&first, &second) // first = 4, second = 3

// 使用函數類型
// 這裏是返回Int類型
// 參數類型是:(Int, Int) -> Int 
func addTwoInts(first: Int, second: Int) -> Int {
  return first + second
}
// 參數類型是:(Int, Int) -> Int 
func multiplyTwoInts(first: Int, second: Int) -> Int {
  return first * second
}

var mathFunction: (Int, Int) -> Int = addTwoInts
mathFunction(1, 2) // return 3
mathFunction = multiplyTwoInts
mathFunction(1, 2) // return 2


// 參數可以作為參數
func printMathResult(mathFunction: (Int, Int) -> Int, first: Int, second: Int) {
  println("Result: \(mathFunction(first, second))")
}

printMathResult(addTwoInts, 3, 5) // prints "Result: 8"
printMathResult(multiplyTwoInts, 3, 5) // prints "Result: 15"

// 函數作為返回類型
func stepForward(input: Int) -> Int {
  return input + 1
}

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

func chooseStepFunction(backwards: Bool) -> ((Int) -> Int) {
  return backwards ? stepBackward : stepForward
}

var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0) // call stepBackward() function

// 參數可以嵌套定義,在C、OC中是不可以嵌套的哦
func chooseStepFunction(backwards: Bool) -> ((Int) -> Int) {
  func stepForward(input: Int) -> Int {
    return input + 1
  }
  
  func stepBackward(input: Int) -> Int {
    return input + 1
  }
  
  return backwards ? stepBackward : stepForward 
}





最後更新:2017-04-03 07:56:55

  上一篇:go NYOJ95-眾數問題
  下一篇:go Android通過JNI實現與C語言的串口通訊操作藍牙硬件模塊