β» λ³Έ ν¬μ€ν μ μ νλΈ Swift Programming Tutorial κ°μλ₯Ό κΈ°λ°μΌλ‘ μ κ° μ§μ μ 리ν Swift λ¬Έλ²μ λν κΈμ λλ€.
Swiftμ λν΄ μ²μ λ°°μλκ°λ κ³Όμ μ λΈλ‘κ·Έμ μ 리νμμ΅λλ€. κΈ°λ³Έμ μΌλ‘ λ€λ₯Έ νλ‘κ·Έλλ° μΈμ΄λ₯Ό λ€λ£¬ μ μ΄ μκΈ°μ μ κ° μλ λΆλΆμ μλ΅λ μ μμ΅λλ€. μ΅λν νλ¦° λΆλΆμ΄ μμ§ μκ² μ κ² μ§λ§ νΉμ μλͺ»λ λΆλΆμ΄ μμΌλ©΄ μλ €μ£ΌμΈμ!
< Functions >
1. ν¨μμ κΈ°λ³Έμ μΈ κ΅¬μ‘°
ν¨μμ κΈ°λ³Έμ μΈ κ΅¬μ‘°λ λ€μκ³Ό κ°μ΅λλ€.
func functionName(parameter1: Type, parameter2: Type) -> ReturnType {
// ν¨μ λ΄λΆμμ μ€νλ μ½λ
return returnValue
}
ν¨μμ μ΄λ¦μ μ ν λλ camel caseμ λ°λΌ μ ν©λλ€. λ¨μ΄ μ¬μ΄μ λμ΄μ°κΈ°κ° μκ³ μ²« κΈμλ μλ¬Έμμ΄λ©°, κ·Έλ€μ λ¨μ΄λΆν°λ λλΆμμΈ νμμ λλ€. μλ₯Ό λ€μ΄ `calculateTotal`, `printMessage` λ±μ΄ μμ΅λλ€.
μλλ 맀κ°λ³μμ λ°ννμ μ΄ λ λ€ μλ κ°μ₯ κ°λ¨ν ν¨μμ½λμ λλ€.
func noArgumentsAndNoReturnValue() {
"I don't know what I'm doing"
}
noArgumentsAndNoReturnValue()
// result : I don't know what I'm doing
argument(μΈμ)μ returnκ°μ΄ λ λ€ νμ μλ ν¨μμ λλ€. playgroundμμλ λ§μ§λ§μ€μ²λΌ ν¨μλ₯Ό νΈμΆν΄λ κ°μ΄ λνλμ§λ§ pure Swiftμμλ print νλ €λ©΄ print()λ₯Ό μ¬μ©ν΄μΌ ν©λλ€.
λ€μμ parameter(맀κ°λ³μ)λ μμΌλ returnκ°μ΄ μλ ν¨μ μμ λ₯Ό λ³΄κ² μ΅λλ€.
func plusTwo(value: Int) {
let newValue = value + 2
}
plusTwo(value: 30) // result μΆλ ₯ μλ¨
ν΄λΉ ν¨μμ 맀κ°λ³μ valueλ Int νμ μ΄λΌκ³ λͺ μλμ΄ μμ΅λλ€. νμ§λ§ λ°ν νμ μ λͺ μνμ§ μκ³ μμ΅λλ€. ν¨μ λ΄λΆμμ `newValue`λ₯Ό κ³μ°νλ κ³Όμ μ μμ§λ§, μ΄ κ°μ λ°ννκ±°λ μΈλΆλ‘ λ ΈμΆμν€λ μμ μ΄ μκΈ° λλ¬Έμ μ€μ λ‘ λ°νκ°μ΄ μλ ν¨μμ λλ€.
λ€μμ parameter(맀κ°λ³μ)μ returnκ°μ΄ λ λ€ μλ ν¨μ μμ μ λλ€.
func newPlusTwo(value: Int) -> Int {
return value + 2
}
newPlusTwo(value: 30)
// 32
μμ μ½λλ `value`λΌλ μ΄λ¦μ `Int`νμ 맀κ°λ³μλ₯Ό λ°μΌλ©°, `Int`νμ μ λ°νν©λλ€. `return`ν€μλλ₯Ό μ¬μ©νμ¬ `value`+2μ κ²°κ³Όλ₯Ό λ°ννκ³ μμ΅λλ€. Swiftμμλ returnμ μλ΅ν΄λ λ°νκ°μ μΆλ‘ κ°λ₯ν κ²½μ°κ° λ§μ΅λλ€.
μμ ν¨μλ μλμ κ°μ΄ `return` μ½λλ₯Ό μλ΅ν΄λ κ°μ κ²°κ³Όλ₯Ό κ°μ§ μ μμ΅λλ€.
func newPlusTwo(value: Int) -> Int {
value + 2
}
newPlusTwo(value: 30)
// 32
Swiftμμ μμ κ°μ΄ λ¨μΌ ννμμ κ²½μ° `return`ν€μλλ₯Ό νμμ μΌλ‘ λͺ μν νμλ μμ΅λλ€. λν Swiftμ νμ μΆλ‘ μ μν΄μ 볡μ‘ν ν¨μ λ΄μμλ μ μ©λ μ μμ΅λλ€. λ€λ§ Swift μ»΄νμΌλ¬κ° ν¨μ λ΄λΆμμ λ§μ§λ§μΌλ‘ μ€νλλ ννμ λλ λ¬Έμ₯μ μλμΌλ‘ λ°νκ°μΌλ‘ μ·¨κΈν©λλ€. μ΄λ λͺ μν λ°νκ°μ νμ κ³Ό μ»΄νμΌλ¬κ° μΆλ‘ ν λ°νκ°μ νμ μ΄ μΌμΉνλ©΄ `return`ν€μλλ₯Ό μλ΅ν μ μμ΅λλ€.
func multiply(a: Int, b: Int) -> Int {
if a > 0 {
a * b
} else {
return 0
}
}
μμ ν¨μμμλ return ν€μλ μμ΄ ifμ μ‘°κ±΄μ΄ μ°ΈμΌ λ `a * b`λ₯Ό λ°ννλ κ²μ λ³Ό μ μμ΅λλ€. μ΄λ μ»΄νμΌλ¬κ° μΆλ‘ ν `a+b`μ κ²°κ³Όκ° λͺ μλ ν¨μ λ°ν νμ μΈ `Int`μ μΌμΉνκΈ° λλ¬Έμ λλ€.
func customAdd(
value1: Int,
value2: Int
) -> Int {
value1 + value2
}
let customAdded = customAdd(
value1: 10,
value2: 20
)
λν ν¨μλ μ μ½λμ κ°μ΄ λ°νκ°μ λ³μμ ν λΉν μ μμ΅λλ€. μ½λλ₯Ό 보μλ©΄ `customAdded`λΌλ μμμ `customAdd`μ λ°νκ°μ ν λΉνλ κ²μ λ³Ό μ μμ΅λλ€.
μ΄λ Swiftκ° ν¨μλ₯Ό μΌκΈ κ°μ²΄(First-class citizen)λ‘ μ·¨κΈνκΈ° λλ¬Έμ λλ€. Swiftμμ ν¨μλ κ°μ²λΌ λ€λ€μ§ μ μκ³ , λ³μλ μμμ ν λΉλμ΄ μ¬μ©ν μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ ν¨μμ λ°νκ°μ λ€λ₯Έ μ°μ°μ μ°Έμ¬μν€κ±°λ, λ€λ₯Έ ν¨μμ μΈμλ‘ μ λ¬νκ±°λ, 쑰건문μμ μ¬μ©νλ λ± λ€μν μ©λλ‘ νμ©ν μ μμ΅λλ€.
2. μΈμ(argument)
(1) λΌλ²¨λ§
Swiftμμ κΈ°λ³Έμ μΌλ‘ ν¨μμ μΈμλ λ΄λΆ λΌλ²¨κ³Ό μΈλΆ λΌλ²¨μ΄ λμΌνκ² μ€μ λ©λλ€. νμ§λ§ ν¨μλ₯Ό μ μν λ μΈμ(argument)μ μΈλΆ λΌλ²¨(external label)κ³Ό λ΄λΆ λΌλ²¨(internal label)μ λ°λ‘ μ§μ ν μ μμ΅λλ€. μΈλΆ λΌλ²¨μ ν¨μλ₯Ό νΈμΆν λ μ¬μ©λλ©°, λ΄λΆλΌλ²¨μ ν¨μ λ΄λΆμμ μ¬μ©λ©λλ€. ν΄λΉ μμ λ₯Ό 보면μ μ€λͺ νκ² μ΅λλ€.
func customAdd(to x: Int, and y: Int) -> Int {
return x + y
}
let sum = customAdd(to: 3, and: 5)
μ½λλ₯Ό 보μλ©΄ `customAdd`ν¨μλ₯Ό νΈμΆν λ μΈμμ `to`μ `and`λΌλ μΈλΆλΌλ²¨μ μ¬μ©ν μ μμ΅λλ€. μΈλΆλΌλ²¨μ ν¨μ νΈμΆ μ κ°λ μ±μ λμ¬μ€λλ€. ν¨μ λ΄λΆμμλ `x`μ `y`λΌλ λ΄λΆ λΌλ²¨μ μ¬μ©νμ¬ μΈμλ₯Ό μ°Έμ‘°ν μ μμ΅λλ€.
μλ μμλ μΈλΆλΌλ²¨μ κ°μ§μ§ μλ ν¨μμ λλ€.
func customMinus(
_ lhs: Int,
_ rhs: Int
) -> Int {
lhs - rhs
}
let customSubtracted = customMinus(20, 10)
μΈλΆλΌλ²¨μ΄ μλ ν¨μλ μΈλΆλΌλ²¨μ `_`λ‘ μ€μ νλ©΄ μλ΅μ΄ κ°λ₯ν©λλ€. μΈλΆ λΌλ²¨μ΄ μκΈ° λλ¬Έμ ν¨μλ₯Ό νΈμΆν λ μΈμ λΌλ²¨λ§ μμ΄ μΈμ κ°λ§ μ μ μ μμ΅λλ€. ν΄λΉ μ½λλ μΈμμ μΈλΆλΌλ²¨μ μ‘΄μ¬νμ§ μμΌλ©° λ΄λΆλΌλ²¨μ κ°κ° `lhs`, `rhs`κ° μ¬μ©λμμ΅λλ€.
(2) argumentμ default value
ν¨μμ 맀κ°λ³μλ κΈ°λ³Έκ°μ κ°μ§ μ μμ΅λλ€. κΈ°λ³Έκ°(default value)μ΄λ 맀κ°λ³μμ 미리 ν λΉλ μ΄κΈ°κ°μ μλ―Έν©λλ€. ν¨μλ₯Ό νΈμΆν λ ν΄λΉ 맀κ°λ³μμ μΈμκ°μ μ λ¬νμ§ μμΌλ©΄, κΈ°λ³Έκ°μ΄ 맀κ°λ³μμ ν λΉλ©λλ€.
func getFullName(
firstName: String = "Foo",
lastName: String = "Bar"
) -> String {
"\(firstName) \(lastName)"
}
// νΈμΆ λ°©λ²
// 1. without argument
getFullName() // "Foo Bar"
// 2. mix&match
getFullName(firstName: "Baz") // "Baz Bar"
getFullName(lastName: "Foo") // "Foo Foo"
// 3. call it with both parameters
getFullName(firstName: "Baz", lastName: "Qux") // "Baz Qux"
μ μ½λμ κ°μ΄ `=`μ ν΅ν΄ 맀κ°λ³μ νμ λ€μ μ΄κΈ°κ°μ λͺ μνλ©΄ λ©λλ€. κΈ°λ³Έκ°μ κ°μ§ 맀κ°λ³μλ₯Ό μ¬μ©νλ©΄ ν¨μ νΈμΆ μ μΈμλ₯Ό μλ΅νκ±°λ μ νμ μΌλ‘ μ λ¬ν μ μμ΅λλ€. (μμ μ½λμμ 3κ°μ§ λ°©λ²μ΄ λμμμ΅λλ€)
3. ν¨μ λ°νκ° νμ© μ¬λΆ
ν¨μμ λ°νκ°μ νμ©νμ§ μκ³ νΈμΆνλ κ²½μ°, μ¦ ν¨μμ λ°νκ°μ λ³μλ μμμ ν λΉνμ§ μλ κ²½μ°, Playgroundμμλ λͺ¨λ ν¨μμ κ²°κ³Όλ₯Ό μ묡μ μΌλ‘ μ¬μ©(consume)νμ§λ§, pure Swift νκ²½μμλ warningμ΄ λνλ©λλ€.
κ²½κ³ κ° λ°μνλ μ΄μ λ ν΄λΉ ν¨μκ° κ°μ λ°ννκ³ μλλ° κ·Έ κ°μ νμ©νμ§ μκΈ° λλ¬Έμ λλ€. μ΄λ μ μ¬μ μΈ λ²κ·Έλ₯Ό μΌκΈ°ν μ μκ³ , μ½λμ κ°λ μ±κ³Ό μ μ§ λ³΄μμ±μ μ ν΄ν μ μμ΅λλ€.
func myCustomAdd(
_ lhs: Int,
_ rhs: Int
) -> Int {
lhs + rhs
}
myCustomAdd(
20,
30
)
μ΄λ¬ν κ²½κ³ λ₯Ό ν΄κ²°νκΈ° μν΄μ λͺ κ°μ§ λ°©λ²μ΄ μ‘΄μ¬ν©λλ€.
(1) λ°νκ°μ΄ νμ μλ κ²½μ° `_`λ₯Ό μ¬μ©
_ = myCustomAdd(20, 30)
λ°νκ°μ νμ©νμ§ μλ μλμ μΈ κ²½μ° `_`μ λ°νκ°μ ν λΉν΄ μλμ μΌλ‘ κ°μ 무μν μ μμ΅λλ€.
(2) `@discardableResult` μ¬μ©
@discardableResult
func myCustomAdd(
_ lhs: Int,
_ rhs: Int
) -> Int {
lhs + rhs
}
μμ κ°μ΄ `@discardableResult` attributeλ₯Ό ν¨μμ μ μ μμ μΆκ°νλ©΄, λ°ν κ°μ΄ μ¬μ©λμ§ μμλ κ²½κ³ κ° λ°μνμ§ μμ΅λλ€. μ΄ attributeλ λ°ν κ°μ νμ©νμ§ μμ κ²μΌλ‘ μμλλ ν¨μμμ μ μ©νκ² μ¬μ©λ μ μμ΅λλ€. ν΄λΉ attributeλ₯Ό ν΅ν΄ κ°λ°μμ μλλ₯Ό λͺ μμ μΌλ‘ ννν©λλ€.
ν¨μμ λ°νκ°μ΄ μλ κ²½μ°, κ·Έ κ²°κ³Όλ₯Ό νμ©νλ κ²μ μ€μν λΆλΆμ λλ€. κ·Έλ¬λ λλ‘λ ν¨μκ° λ³΅μ‘ν μμ μ μννκ³ μ±κ³΅μ¬λΆλ₯Ό λνλ΄λ Booleanκ°λ§ λ°ννλ κ²½μ°κ° μμ΅λλ€. μ΄ Booleanκ°μ΄ μ€μ λ‘ μ€μνμ§ μλ κ²½μ°λ μμ μ μμ΅λλ€. μ΄λ `@discardableResult`μμ±μ μ¬μ©νλ©΄ λ°νκ°μ 무μνκ³ ν¨μλ₯Ό νΈμΆν μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ μ½λμ λͺ νμ±μ μ μ§νλ©΄μ νμν κ²½μ°μλ§ λ°νκ°μ νμ©ν μ μμ΅λλ€.
4. μ€μ²© ν¨μ
Swiftμμλ ν¨μ λ΄λΆμ λ€λ₯Έ ν¨μλ₯Ό μ μν μ μμ΅λλ€. μλμ μ½λλ₯Ό ν΅ν΄ μ€λͺ λλ¦¬κ² μ΅λλ€.
func doSomethingComplicated(
with value: Int
) -> Int {
func mainLogic(value: Int) -> Int {
value + 2
}
return mainLogic(value: value + 3)
}
doSomethingComplicated(with: 30)
// 35
μμ μ½λμμ `mainLogic`μ΄λΌλ μ€μ²© ν¨μκ° μ μλμ΄ μμ΅λλ€. μ΄ ν¨μλ `doSomethingComplicated` ν¨μ λ΄λΆμμλ§ μ¬μ©ν μ μμ΅λλ€. μ΄ μΈλΆν¨μλ₯Ό νΈμΆνλ λ€λ₯Έ λΆλΆμ΄λ μ μμ μΈ λ²μμμλ μ€μ²©ν¨μλ₯Ό μ§μ νΈμΆν μ μμ΅λλ€. μ€λ‘μ§ μΈλΆν¨μ λ΄μμλ§ νμν μ§μμ μΈ μμ μ μννλλ‘ μ€κ³λμ΄ μμ΅λλ€.
μ΄λ μ½λμ λͺ¨λνμ μΊ‘μνμ κ΄λ ¨ μμ΅λλ€. μ€μ²©ν¨μλ μΈλΆμ λ ΈμΆλμ§ μκ³ , μΈλΆ ν¨μμ λ΄λΆ ꡬνμ κ°μΆλ λ° λμμ μ€λλ€. μ΄λ μ½λμ κ°λ μ±κ³Ό μ μ§ λ³΄μμ± ν₯μμλ μν₯μ μ€λλ€.
5. Function Signature
Function Signature(ν¨μ μκ·Έλμ²)λ ν¨μμ μ΄λ¦κ³Ό 맀κ°λ³μμ νμ , λ°ν νμ μ μλ―Έν©λλ€. ν¨μ μκ·Έλμ²λ ν¨μμ κ³ μ ν μλ³μλ‘ κ°μ£Όλλ©°, ν¨μλ₯Ό μ μνκ³ νΈμΆν λ μ¬μ©ν©λλ€. μ΄λ ν¨μμ ννμ λμμ λͺ ννκ² μ μνλ λ° λμμ μ€λλ€.
func addNumbers(_ number1: Int, _ number2: Int) -> Int {
// λ μ μλ₯Ό λν κ²°κ³Όλ₯Ό λ°ν
}
μμ ν¨μμ μκ·Έλμ²λ λ€μκ³Ό κ°μ΅λλ€. μ΄λ¦μ΄ `addNumbers`μ΄κ³ , λ κ°μ `Int` νμ 맀κ°λ³μ(`number1`κ³Ό `number2`)λ₯Ό κ°μ§λ©°, λ°ν νμ μ `Int`μ λλ€.
ν¨μ μκ·Έλμ²λ ν¨μλ₯Ό νΈμΆν λ μ¬μ©λ©λλ€. νΈμΆν λ ν¨μ μ΄λ¦κ³Ό μΈμκ°μ νμ λ° μμκ° ν¨μ μκ·Έλμ²μ μΌμΉν΄μΌ μ»΄νμΌλ¬κ° μ¬λ°λ₯Έ ν¨μλ₯Ό μ°Ύμ μ€ννκ³ , νμ μμ μ±μ 보μ₯ν μ μμ΅λλ€.
λν μ΄λ ν¨μμ μ€λ²λ‘λ©(Overloading)μλ μ€μν μν μ ν©λλ€. μ€λ²λ‘λ©μ λμΌν μ΄λ¦μ κ°μ§ ν¨μκ° λ€λ₯Έ 맀κ°λ³μ νμ λλ 맀κ°λ³μ κ°μλ₯Ό κ°μ§λ κ²μ μλ―Έν©λλ€. μ΄λ ν¨μ μκ·Έλμ²μΈ κ³ μ ν μλ³μκ° λ€λ₯Έ ν¨μλ€κ³Ό ꡬλΆνμ¬ νΈμΆ μ μ μ ν ν¨μλ₯Ό μ νν μ μλλ‘ ν©λλ€.
func greet() {
print("Hello!")
}
func greet(name: String) {
print("Hello, \(name)!")
}
func greet(age: Int) {
print("You are \(age) years old!")
}
μμ μ½λμμ `greet`λΌλ μ΄λ¦μ κ°μ§ ν¨μκ° μΈ κ°μ§ λ²μ μΌλ‘ μ€λ²λ‘λ©λμμ΅λλ€. μ΄μ²λΌ μ€λ²λ‘λ©μ μ¬μ©νμ¬ μ μ¬ν μμ μ μννλ ν¨μλ€μ νλμ μ΄λ¦μΌλ‘ κ·Έλ£Ήνν μ μμ΅λλ€. κ°μ μ΄λ¦μ΄μ§λ§ κ°κ° 맀κ°λ³μ νμ μ΄ λ€λ₯Έ κ³ μ ν ν¨μ μκ·Έλμ²λ₯Ό κ°μ§κ³ μκΈ°μ μ»΄νμΌλ¬λ μ μ ν ν¨μλ₯Ό μ°Ύμ μ μμ΅λλ€.
μ¬κΈ°κΉμ§ functionsμ λν μ 리μμ΅λλ€. λ€μ ν¬μ€ν μ Closuresμ λν λ΄μ©μΌλ‘ λμμ€κ² μ΅λλ€.
κ°μλ freeCodeCamp μ±λμ μμμΈλ°, VandadλΌλ λΆμ΄ μ§ννλ 7μκ° λΆλμ full tutorial for beginnersμ λλ€. ν΄λΉ κ°μλ νλ‘κ·Έλλ° μΈμ΄λ₯Ό Swiftλ‘ μ²μ μ νλ μ¬λλ€μκ²λ λ€μ μ΄λ €μΈ μ μλ€κ³ μκ°ν©λλ€. μ λ κΈ°μ΄μ μΈ λΆλΆμ λν μΌν μ€μμ±μ κΉκ² μλ €μ£Όλ κ² κ°μμ κ°μλ₯Ό ννμ΅λλ€. μμ΄ κ°μμ΄λ©° μμ΄μλ§ λλ μλλ²μ κΈ°λ₯μ΄ μ 곡λκΈ°μ, νΉμ νλ‘κ·Έλλ° μΈμ΄λ₯Ό λ€λ£¬ μ μ΄ μλ λΆλ€ μ€ Swiftμ λν΄ μλ‘κ² λ°°μ°κ³ μ νλ€λ©΄ κ°μΆλ립λλ€!
ν΄λΉ κ°μ μμμ μλμ κ±Έμ΄λκ² μ΅λλ€. νΉμ νλ¦° λΆλΆμ΄λ μΆκ°νκ³ μΆμ λΆλΆμ΄ μμΌλ©΄ μλ €μ£ΌμΈμ.
κ°μ μ 체λ₯Ό μ리μ¦λ‘ μ μ μ μλλ‘ λ Έλ ₯νκ² μ΅λλ€.
<μ΄μ κΈ>
2023.05.08 - [TIL/Swift] - [Swift] Swift κΈ°λ³Έ λ¬Έλ² μ 리 1. Variables
2023.05.15 - [TIL/Swift] - [Swift] Swift κΈ°λ³Έ λ¬Έλ² μ 리 2. Operators & If-else