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).