Swift Functions
Functions, Nested Functions, First-Class Citizens
1. Defining and Calling Functions π©βπ»
Syntax
func name (parameters) -> return type {
function body
}
- Name: ν¨μλ₯Ό μ μν λ μμ±νλ€. ν¨μλ₯Ό μ μνκ³ νΈμΆν λ μ¬μ©νκΈ° μν νμ μμλ€.
- Parameters(Optional): ν¨μλ₯Ό μ μν λ μμ±νλ€. ν¨μκ° μ€νλ λ μ λ ₯λμ΄ λ΄λΆμμ μ¬μ©ν κ°λ€λ‘, νλ λλ κ·Έ μ΄μ μ μν μ μλ€.
- Return Type(Optional): ν¨μλ₯Ό μ μν λ μμ±νλ€. ν¨μκ° μ€νμ λ§μΉκ³ μ’ λ£λλ©° λ°νν κ°μΌλ‘, λ¨ νλμ νμ μ μ μν μ μλ€.
- Arguments(Optional): ν¨μλ₯Ό νΈμΆν λ μμ±νλ€. ν¨μλ₯Ό μ€ννκΈ° μν΄ ν¨μ μΈλΆμμ
μ λ¬νλ κ°μΌλ‘, λ°λμ
Parametersμμμ λ° νμ κ³Ό μΌμΉν΄μΌνλ€.
1 ) Defining Functions
func greet(person: String) -> String {
"Hello, \(person)!"
}
2 ) Calling Functions
print(greet(person: "Anna")) // Hello, Anna!
ν¨μμ
Name,Parameters,Return Typeμ ν¨μκ° λ¬΄μ¨ μΌμ ν μ§, 무μμ μ λ ₯ λ°μμ§, 무μμ λ°ν ν μ§λ₯Ό μ€λͺ νλ μ 보μ΄λ―λ‘ λͺ νν μμ±νλλ‘ νλ€.
2. Function Parameters and Return Values π©βπ»
1. Functions without Parameters
func sayHelloWorld() -> String {
"hello, world"
}
print(sayHelloWorld()) // hello, world
2. Functions with Multiple Parameters
func greet(person: String) -> String {
"Hello, \(person)!"
}
func greetAgain(person: String) -> String {
"Hello again, \(person)!"
}
func greet(person: String, alreadyGreeted: Bool) -> String {
if alreadyGreeted {
return greetAgain(person: person)
} else {
return greet(person: person)
}
}
print(greet(person: "Tim", alreadyGreeted: false)) // Hello, Tim!
print(greet(person: "Tim", alreadyGreeted: true)) // Hello again, Tim!
μ μ½λ λΈλμμ μ μν func greet(person: String) -> Stringμ
μλ μ½λλΈλμμ μ μν func greet(person: String, alreadyGreeted: Bool) -> Stringμ λ€λ₯Έ ν¨μλ€.
ν¨μ
nameμ΄ κ°λλΌλparametersκ° λ€λ₯΄λ©΄, λ€λ₯Έ ν¨μλ‘ κ΅¬λΆλλ€. μ΄λ₯ΌPolymorphism(λ€νμ±)μ΄λΌκ³ νλ€.
λ¨, μ΄λ¬ν ꡬλΆμreturn typeμ μν₯μ μ£Όμ§ μλλ€.
3. Functions without Return Values
Return Type μ΄ μμ λλ Voidλ₯Ό Return Type μΌλ‘ μ μνλ€.
func greetVoid(person: String) -> Void {
print("Hello, \(person)!")
}
Return Type μ VoidμΌ λ ννμ¬ μλ΅λ μ μλ€(It implicitly returns Void).
func greetVoid(person: String) {
print("Hello, \(person)!")
}
greetVoid(person: "Harry") // Hello, Harry!
μλ°ν λ§νλ©΄ Return Type μ μλ΅νλλΌλ ν¨μλ
VoidλΌλ νμ μ νΉμν κ°μ λ°ννλ€.
μ΄ κ°μ()λ‘ μ°μ¬μ§Empty Tupleμ΄λ€.
λͺ
μμ μΌλ‘ λ°ν κ°μ΄ μλ ν¨μλ₯Ό νΈμΆν λλ λ°λμ let, var λ‘ λ°μμΌ νλ€. κ·Έλ μ§ μμΌλ©΄ compile-time errorκ° λ°μνλ€.
λ§μ½, ν¨μμ λ°νκ°μ μ¬μ©ν νμκ° μλ€λ©΄ κ°λ¨ν _λ‘ λ°μΌλ©΄ λλ€.
func printAndCount(string: String) -> Int {
print(string)
return string.count
}
func printWithoutCounting(string: String) {
let _ = printAndCount(string: string)
}
print(printWithoutCounting(string: "hello, world"))
hello, world
()
4. Functions with Multiple Return Values
Swift λ tupleμ μ΄μ©ν΄ νλμ compound λ‘ μ¬λ¬ λ³μμ κ°μ ν λΉν μ μλ€.
let (alphabetA, alphabetB) = ("A", "B")
print("alphabetA is \(alphabetA) and alphabetB is \(alphabetB)")
alphabetA is A and alphabetB is B
One compound return value : λ§μ°¬κ°μ§λ‘ ν¨μμ λ°νκ° μμ tupleμ μ΄μ©ν΄ μ¬λ¬ κ°μ νλμ compound λ‘ λ°νν μ μλ€.
let intArray: [Int] = [31, 6, 43, 13, 6, 1, 56, 5, 88, 24]
func minMax(array: [Int]) -> (Int, 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)
}
1 ) λ°νκ°μ tupleμ μ΄μ©ν΄ κ°κ° Int νμ
μ μμ minNumber, maxNumberμ ν λΉνλ€
let (minNumber, maxNumber): (Int, Int) = minMax(array: intArray)
print("min is \(minNumber) and max is \(maxNumber)")
min is 1 and max is 88
2 ) λ°νκ°μ tuple νμ
μ λ¨μΌ μμ boundsμ κ·Έλλ‘ ν λΉνλ€. κ·Έλ¦¬κ³ κ° tuple μλ min, max λΌλ labelμ λΆμ¬μ€λ€
let bounds: (min: Int, max: Int) = minMax(array: intArray)
print("min is \(bounds.min) and max is \(bounds.max)")
min is 1 and max is 88
3 ) λ§μ½, ν¨μμ Return Type μ μ μν λ labelμ λΆμ¬μ£Όλ©΄ λ³λμ label μ§μ μμ΄ ν΄λΉ label μ μ΄μ©ν μ μλ€
let intArray: [Int] = [31, 6, 43, 13, 6, 1, 56, 5, 88, 24]
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: intArray)
print("min is \(bounds.min) and max is \(bounds.max)")
min is 1 and max is 88
5. Optional Tuple Return Types
ν¨μκ° λ°ννλ μ 체 Tuple μ΄ nilμΌ κ°λ₯μ±μ΄ μλ€λ©΄, (Int, Int)? λλ (String, Int, Bool)?κ³Ό κ°μ΄ tuple μ체μ
?λ₯Ό λΆμ¬ Optiional Tuple Typesλ₯Ό λ°ννλλ‘ ν μ μλ€.
(Int, Int)?λOptional Tuple Typeμ΄κ³
(Int?, Int?)λOptional Int Typeμ ν¬ν¨νλTuple Typeμ΄λ€.
Optional Tuple Typeμ μ¬μ©νλ©΄ μ 체TupleλΏ μλλΌTupleλ΄μ κ°λ³ κ°λ μλμΌλ‘Optional Typeμ΄ λλ€.
let intArray: [Int] = [31, 6, 43, 13, 6, 1, 56, 5, 88, 24]
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty { return nil }
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)
}
if let bounds = minMax(array: []) {
print("min is \(bounds.min) and max is \(bounds.max)")
} else {
print("input array is empty.")
}
if let bounds = minMax(array: intArray) {
print("min is \(bounds.min) and max is \(bounds.max)")
} else {
print("input array is empty.")
}
input array is empty.
min is 1 and max is 88
6. Function with an Implicit Return
ν¨μμ μ 체 λ³Έλ¬Έμ΄ λ¨μΌ ννμμΈ κ²½μ° ν¨μλ μμμ μΌλ‘ ν΄λΉ ννμμ λ°ννλ€.
func add(_ num1: Int, _ num2: Int) -> Int {
num1 + num2
}
print(add(6, 8)) // 14
3. Function Argument Labels and Parameter Names π©βπ»
Swift ν¨μλ argument labelκ³Ό parameter nameμ λͺ¨λ κ°λλ€. argument label μ ν¨μλ₯Ό νΈμΆν λ
μ¬μ©λκ³ , parameter name μ ν¨μκ° μ€νλ λ λ΄λΆμμ μ¬μ©λλ€.
Syntax
func someFunction(argumentLabel parameterName: Int) {
// In the function body, parameterName refers to the argument value
// for that parameter.
}
λ§μ½, argument label μ μλ΅νλ©΄ κΈ°λ³Έμ μΌλ‘ paramter name μ argument label λ‘ μ¬μ©νκ² λλ€.
| argument label | parameter name |
|---|---|
| Optional | Essential |
| Used to call a function | Used when a function is executed |
| Non-Unique(Duplicate labels are allowed) | Unique |
parameter name κ³Ό λ¬λ¦¬ argument label μ
non-uniqueμ΄λ―λ‘ λμΌν μ΄λ¦μ μ¬μ©ν μ μμΌλ μ½λλ₯Ό μ½κΈ° μ½λλ‘ μ μ ν μ΄λ¦μ μ¬μ©νλ κ²μ΄ μ’λ€.
1. Specifying Argument Labels
argument λ₯Ό default κ°μΈ parameter name κ³Ό λμΌνκ² μ¬μ©νμ§ μκ³ λ€λ₯Έ μ΄λ¦μ μ¬μ©νλ €λ©΄ parameter name μμ argument label μ μμ±νλ€.
func greet(person: String, from hometown: String) -> String {
return "Hello \(person)! Glad you could visit from \(hometown)."
}
print(greet(person: "Bill", from: "Cupertino"))
Hello Bill! Glad you could visit from Cupertino.
2. Omitting Argument Labels
argument label μ체λ₯Ό μλ΅νκΈΈ μνλ€λ©΄ arguemnt label μ _ μ μ¬μ©νλ€.
func someFunction(_ firstParameterName: Int, secondParameterName: Int) {
// In the function body, firstParameterName and secondParameterName
// refer to the argument values for the first and second parameters.
}
someFunction(1, secondParameterName: 2)
4. Special Function Parameters π©βπ»
1. Default Parameter Values
μ°μ TypeScript μ μλμ 보μ.
const add = (num1: number, num2: number = 10): number => +num1 + +num2
console.log(add(5, 20)) // 25
console.log(add(5)) // 15
console.log(add(5, undefined)) // 15
console.log(add(5, NaN)) // NaN
Swift μμμ μλμ λ€μκ³Ό κ°λ€.
func add(a num1: Int, b num2: Int = 10) -> Int {
num1 + num2
}
print(add(a: 5, b: 20)) // 25
print(add(a: 5)) // 15
Swift λ Int λμ nil μ λ°μ μ μκΈ° λλ¬Έμ νΈμΆλ λ num2 argument μμ΄ νΈμΆλ κ²½μ°μ λν΄μλ§
default value κ° μλνλ€.
print(add(a: 5, b: nil)) // 'nil' is not compatible with expected argument type 'Int'
argument κ° μλ΅λ κ²μ΄ μλκ³ Int νμ μ κΈ°λνλ λ° nil μ΄ λ€μ΄μ μλ¬κ° λ°μνλ€.
μ¦, μ TypeScript μμ undefined κ° λμ΄μ€λ κ²μ²λΌ Swift μμ nilμ μ²λ¦¬νλ €λ©΄, Optional Parameters λ₯Ό μ¬μ©νκ³ ,
nil μ undefined μ λ¬λ¦¬ μ΄κΈ°νλ λμμΌλ nil μ΄λ―λ‘ (μλ°ν λ§νλ©΄ μμμ TypeScript μμλ null μ λ°μ§λ λͺ»νλ€)
argument λ‘ nilμ λ£μ΄ νΈμΆνλ©΄ parameter μ Optional<Int> νμ
μ nilμ΄ μ μ₯λμ΄ λ€μ΄μ΄μΌλ‘
default parameter value κ° μλνμ§ μμ λ΄λΆμμ λ³λλ‘ μ²λ¦¬ν΄μΌνλ€.
func add(a num1: Int, b num2: Int? = 10) -> Int {
guard let num2 = num2 else { return num1 + 10 } // 'default parameter value' κ° μλνμ§ μλ κ²μ λν 보μ
return num1 + num2
}
print(add(a: 5, b: 20)) // 25
print(add(a: 5)) // 15
print(add(a: 5, b: nil)) // 15
λν,
default parameter valueλ₯Ό μ¬μ©ν λ μ£Όμν κ²μPolymorphism(λ€νμ±)μ μν΄ μ°μ μμ μdefault parameter valueλ 무μλ μ μλ€λ κ²μ΄λ€.
func add(a num1: Int) -> Int {
num1 + 100
}
func add(a num1: Int, b num2: Int = 10) -> Int {
num1 + num2
}
print(add(a: 5, b: 20)) // 25
print(add(a: 5)) // 105
Polymorphism(λ€νμ±)μ μν΄ func add(a num1: Int) -> Intμ νΈμΆμ΄ μ°μ μ λκΈ° λλ¬Έμ
func add(a num1: Int, b num2: Int = 10) -> Intμ default valueλ₯Ό μ΄μ©ν νΈμΆμ μλνμ§ μλλ€.
2. Variadic Parameters
- Variadic Parameters
func arithmeticMean(_ numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
print(arithmeticMean(2)) // 2.0
print(arithmeticMean(1, 2, 3, 4, 5)) // 3.0
print(arithmeticMean(3, 8.25, 18.75)) // 10.0
- Array Parameter
func arithmeticMean(_ numbers: [Double]) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
print(arithmeticMean([2])) // 2.0
print(arithmeticMean([1, 2, 3, 4, 5])) // 3.0
print(arithmeticMean([3, 8.25, 18.75])) // 10.0
Variadic ParametersμArray Parameterμ λ΄λΆ μλμ[Double]λ‘ κ°μ§λ§,
Variadic ParametersλDouble nκ°λ₯Ό argumentsλ‘ λ°κ³ ,
Array Parameterλ[Double] 1κ°λ₯Ό argumentλ‘ λ°λλ€λ κ²μ΄ λ€λ₯΄λ€.
Swift μμ Variadic Parametersλ TypeScript μμ Rest Parametersλ₯Ό μ΄μ©ν΄ λ€μκ³Ό κ°μ΄ ꡬνλλ κ²κ³Ό κ°λ€.
const arithmeticMean = (...numbers: number[]): number => {
let total: number = 0
for (const num of numbers) {
// @ts-ignore
total += Number(num) // total = Number(+total + +num)
}
return Number(total) / numbers.length
}
console.log(arithmeticMean(2)) // 2
console.log(arithmeticMean(1, 2, 3, 4, 5)) // 3
console.log(arithmeticMean(3, 8.25, 18.75)) // 10
3. In-Out Parameters
ν¨μμ parametersλ κΈ°λ³Έμ μΌλ‘ constants μ΄λ―λ‘ μμ ν μ μλ€.
λ§μ½, parametersλ₯Ό μμ νκ³ , ν¨μκ° μ’
λ£λ νμλ, μ¦, ν¨μ scope λ°μμλ μ΄ κ°μ μ μ§νκ³ μΆλ€λ©΄
parameter type μμ inout ν€μλλ₯Ό μ¬μ©ν΄ In-Out Parametersλ‘ λ§λ€ μ μλ€.
In-Out Parametersλ variablesλ§ argumentsλ‘ λ°μ μ μλ€. constantsλ literalsλ
μμ μ΄ λΆκ°νλ―λ‘ μ
λ ₯ λ°μ μ μλ€.
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
someInt is now 107, and anotherInt is now 3
In-Out Parametersλ₯Ό μ 리νλ©΄ λ€μκ³Ό κ°λ€.
- In-Out Parameters λ parameter type μμ
inoutν€μλλ₯Ό μ¬μ©ν΄ λ§λ λ€.- In-Out Parameters λ₯Ό μ¬μ©ν ν¨μλ₯Ό νΈμΆν λ
argumentsμμ&ν€μλλ₯Ό λΆμ¬ νΈμΆνλ€.μλ μμλ λ€μκ³Ό κ°λ€.
- ν¨μκ° νΈμΆλ λ
argumentsμ κ°μ΄ parameters μ볡μ¬λλ€.- 볡μ¬λ arguments μ κ°μ΄ ν¨μμ
bodyμμμμ λλ€.- ν¨μκ° μ’ λ£λ λ
argumentsμ Pointer λ₯Ό μ΄μ©ν΄ κ°μμμ νλ€.
5. Function Types π©βπ»
func addTwoInts(_ a: Int, _ b: Int) -> Int {
return a + b
}
func multiplyTwoInts(_ a: Int, _ b: Int) -> Int {
return a * b
}
μ λ ν¨μμ Function Types λ λ€μκ³Ό κ°λ€. (Int, Int) -> Int
func printHelloWorld() {
print("hello, world")
}
μ ν¨μμ Function Types λ λ€μκ³Ό κ°λ€. () -> Void
1. Using Function Types
Swift μμλ Function Types μμ λ€λ₯Έ Typesμ κ°μ΄ μ¬μ©ν μ μλ€.
1 ) Function Declarations
func addTwoInts(_ a: Int, _ b: Int) -> Int {
a + b
}
func multiplyTwoInts(_ a: Int, _ b: Int) -> Int {
a * b
}
var mathFunction: (Int, Int) -> Int
mathFunction = addTwoInts(_:_:)
print(mathFunction(5, 7)) // 12
mathFunction = multiplyTwoInts(_:_:)
print(mathFunction(5, 7)) // 35
2 ) Function Expressions
λ€μ μμ λ Function Typesλ₯Ό μ΄μ©ν΄ λ³μλ μμμ νμ
μ μ§μ νκ³ , Closuresλ₯Ό ν λΉν΄ ν¨μλ₯Ό μ μΈνλ€.
μ΄κ²μ μ Function Declarationsμ λμΌν κ²°κ³Όλ₯Ό κ°λλ€.
(μ΄ κ²½μ° TDZ λ‘ μΈν Hoistingκ°λ
λ λμΌνκ² μ μ©λλ€.)
// With Function Types
let addTwoInts: (Int, Int) -> Int = { (a: Int, b: Int) in
a + b
}
// Without Function Types
let multiplyTwoInts = { (a: Int, b: Int) in
a * b
}
print(addTwoInts(5, 7)) // 12
print(multiplyTwoInts(5, 7)) // 35
μ μ½λ μμ TypeScript μ λΉκ΅ν΄λ³΄μ
// With Function Types
const addTwoInts: (num1: number, num2: number) => number
= (a, b) => a + b
// Without Function Types
const multiplyTwoInts = (a: number, b: number): number => a * b
console.log(addTwoInts(5, 7)) // 12
console.log((multiplyTwoInts(5, 7))) // 35
3 ) Define Function Types from Type Alias
Protocolsλ₯Ό μ΄μ©ν΄ Classes, Structures λ±κ³Ό κ°μ νμ
μ Blueprintλ₯Ό μ 곡νλ― ν¨μ μμ typealiasλ₯Ό μ΄μ©ν΄ Typeμ
κ°μ ν μ μλ€.
typealias ArithmeticCalc = (Int, Int) -> Int
let addTwoInts: arithmeticCalc = { $0 + $1 }
let multiplyTwoInts: arithmeticCalc = { $0 * $1 }
print(addTwoInts(5, 7)) // 12
print(multiplyTwoInts(5, 7)) // 35
μ μ½λ μμ TypeScript μ λΉκ΅ν΄λ³΄μ
type GenericFunc = <Number>(a: number, b: number) => number
const addTwoInts: GenericFunc = (a, b) => a + b
const multiplyTwoInts: GenericFunc = (a, b) => a * b
λλ
type GenericType<Number> = (a: number, b: number) => number
const addTwoInts: GenericType<Number> = (a, b) => a + b
const multiplyTwoInts: GenericType<Number> = (a, b) => a * b
λ¬Όλ‘ μλ΅λ κ°λ₯νλ€.
type GenericFunc = (a: number, b: number) => number
const addTwoInts: GenericFunc = (a, b) => a + b
const multiplyTwoInts: GenericFunc = (a, b) => a * b
console.log(addTwoInts(5, 7)) // 12
console.log((multiplyTwoInts(5, 7))) // 35
2. Function Types as Parameter Types
Swift μ ν¨μλ First-Class Citizenμ΄λ―λ‘ parameters κ° λ μ μλ€.
let addTwoInts: (Int, Int) -> Int = { (a: Int, b: Int) in
a + b
}
let multiplyTwoInts = { (a: Int, b: Int) in
a * b
}
func printMathResult(mathFunction function: (Int, Int) -> Int, _ a: Int, _ b: Int) {
print("Result: \(function(a, b))")
}
printMathResult(mathFunction: addTwoInts, 5, 7) // Result: 12
printMathResult(mathFunction: multiplyTwoInts, 5, 7) // Result: 35
printMathResult(mathFunction:_:_:)μ 첫 λ²μ§Έ parameter λ (Int, Int) -> Int νμ
μ ν¨μλ₯Ό argumentλ‘ λ°λλ€.
μ μ½λ μμ TypeScript μ λΉκ΅ν΄λ³΄μ
const addTwoInts: (num1: number, num2: number) => number
= (a, b) => a + b
const multiplyTwoInts = (a: number, b: number) => a * b
// const printMathResult = (mathFunction: Function, a: number, b: number) => console.log(`Result: ${mathFunction(a, b)}`)
const printMathResult = (mathFunction: (num1: number, num2:number) => number, a: number, b: number) => {
console.log(`Result: ${mathFunction(a, b)}`)
}
printMathResult(addTwoInts, 5, 7) // Result: 12
printMathResult(multiplyTwoInts, 5, 7) // Result: 35
3. Function Types as Return Types
λ§μ°¬κ°μ§λ‘ Swift μ ν¨μλ First-Class Citizenμ΄λ―λ‘ return type μ΄ λ μ μλ€.
0λ³΄λ€ ν¬λ©΄ stepBackward(_:) ν¨μλ₯Ό μ€ννκ³ , 0λ³΄λ€ μμΌλ©΄ stepForward(_:) ν¨μλ₯Ό μ€νν΄ 0μ λλ¬νλ λ‘μ§μ μΆλ ₯ν΄λ³΄μ.
func stepForward(_ input: Int) -> Int {
print(#function)
return input + 1
}
func stepBackward(_ input: Int) -> Int {
print(#function)
return input - 1
}
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
backward ? stepBackward(_:) : stepForward(_:)
}
chooseStepFunction(backward:) ν¨μλ (Int) -> Int ν¨μλ₯Ό return νλ€.
func movingStart(initialValue: Int) {
var currentValue = initialValue
let moveNearToZero = chooseStepFunction(backward: currentValue > 0)
print("Counting to zero:")
while currentValue != 0 {
print("\(currentValue)... Call ", terminator: "")
currentValue = moveNearToZero(currentValue)
}
print("zero!\n")
}
movingStart(initialValue: 4)
movingStart(initialValue: -3)
Counting to zero:
4... Call stepBackward(_:)
3... Call stepBackward(_:)
2... Call stepBackward(_:)
1... Call stepBackward(_:)
zero!
Conting to zero:
-3... Call stepForward(_:)
-2... Call stepForward(_:)
-1... Call stepForward(_:)
zero!
μ μ½λ μμ TypeScript μ λΉκ΅ν΄λ³΄μ
const stepForward = (input: number): number => input + 1
const stepBackward = (input: number): number => input - 1
const chooseStepFunction = (backward: boolean): (input: number) => number => {
return backward ? stepBackward : stepForward
}
const movingStart = (initialValue: number) => {
let currentValue = initialValue
const moveNearToZero = chooseStepFunction(initialValue > 0)
console.log("Counting to zero:")
while (currentValue !== 0) {
console.log(`${currentValue}... Call ${moveNearToZero.name}`)
currentValue = moveNearToZero(currentValue)
}
console.log("zero!\n")
}
movingStart(4)
movingStart(-3)
Counting to zero:
4... Call stepBackward
3... Call stepBackward
2... Call stepBackward
1... Call stepBackward
zero!
Counting to zero:
-3... Call stepForward
-2... Call stepForward
-1... Call stepForward
zero!
6. Nested Functions π©βπ»
μμμ μμ±λ ν¨μλ λͺ¨λ Global Scopeμ μ κ·Όμ±μ κ°λ Global Functionsλ€.
νμ§λ§ ν¨μμ body μμ λ€λ₯Έ ν¨μλ₯Ό μ μν μ μλλ° μ΄λ₯Ό Nested FunctionsλΌ νλ€.
μ Function Types as Return Types λ₯Ό Nested Functionsλ‘ λ°κΏλ³Έλ€.
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
func stepForward(_ input: Int) -> Int {
print(#function)
return input + 1
}
func stepBackward(_ input: Int) -> Int {
print(#function)
return input - 1
}
return backward ? stepBackward(_:) : stepForward(_:)
}
chooseStepFunction(backward:) ν¨μλ₯Ό μν΄ μ¬μ©λλ stepForward(_:), stepBackward(_:) ν¨μλ₯Ό
chooseStepFunction(backward:) ν¨μμ bodyμ μ€μ²©ν΄ μ κ·Όμ μ ννκ³ κ°λ
μ±μ λμλ€.
func movingStart(initialValue: Int) {
var currentValue = initialValue
let moveNearToZero = chooseStepFunction(backward: currentValue > 0)
print("Counting to zero:")
while currentValue != 0 {
print("\(currentValue)... Call ", terminator: "")
currentValue = moveNearToZero(currentValue)
}
print("zero!\n")
}
movingStart(initialValue: 4)
movingStart(initialValue: -3)
Conting to zero:
4... Call stepBackward(_:)
3... Call stepBackward(_:)
2... Call stepBackward(_:)
1... Call stepBackward(_:)
zero!
Conting to zero:
-3... Call stepForward(_:)
-2... Call stepForward(_:)
-1... Call stepForward(_:)
zero!
μ μ½λ μμ TypeScript μ λΉκ΅ν΄λ³΄μ
const chooseStepFunction = (backward: boolean): (input: number) => number => {
const stepForward = (input: number): number => input + 1
const stepBackward = (input: number): number => input - 1
return backward ? stepBackward : stepForward
}
const movingStart = (initialValue: number) => {
let currentValue = initialValue
const moveNearToZero = chooseStepFunction(initialValue > 0)
console.log("Counting to zero:")
while (currentValue !== 0) {
console.log(`${currentValue}... Call ${moveNearToZero.name}`)
currentValue = moveNearToZero(currentValue)
}
console.log("zero!\n")
}
movingStart(4)
movingStart(-3)
Counting to zero:
4... Call stepBackward
3... Call stepBackward
2... Call stepBackward
1... Call stepBackward
zero!
Counting to zero:
-3... Call stepForward
-2... Call stepForward
-1... Call stepForward
zero!
Nested Functionsλ₯Ό νμ©νλ©΄ μ μμμ μ κ·Όν νμκ° μλ ν¨μμscopeλ₯Ό μ νν΄ μ½λλ₯Ό λμ± μμ νκ³ κ°λ μ± λκ² λ§λ€ μ μλ€.
λ¨, Swift μμλ μ TypeScript μμμ λ¬λ¦¬ μ€μ²©λ ν¨μλ₯Όletλλvarλ‘ μ μν μ μλ€. λ°λμfuncν€μλλ₯Ό μ΄μ©ν΄ μ μν΄μΌνλ€ (cf. Closure Expressions λ₯Ό μ°Έκ³ νλ€).
Reference
- βFunctions.β The Swift Programming Language Swift 5.7. accessed Oct. 19, 2022, Swift Docs Chapter 5 - Functions.
- βFirst-class citizen.β Wikipedia. Oct. 15, 2022, Wikipedia - First Class Citizen.
- βFirst-class function.β Wikipedia. Jul. 14, 2022, Wikipedia - First Class Function.
- βSpread syntax.β MDN Web Docs. Sep. 19, 2022, MDN - Spread Syntax(β¦).
- βRest parameters.β MDN Web Docs. Sep. 19, 2022, MDN - Rest Parameters(β¦args).