[Swift] - 함수, 제어구문, 옵셔널

dongle·2022년 11월 16일
0

함수의 선언

기본 형태

func 함수이름(매개변수1이름: 매개변수1타입, 매개변수2이름: 매개변수2타입 ...) -> 반환타입 {
    return 반환값
}

ex)

func sum(a: Int, b: Int) -> Int {
    return a + b
}

반환 값이 없는 함수

func 함수이름(매개변수1이름: 매개변수1타입, 매개변수2이름: 매개변수2타입 ...) -> Void {
    return
}

ex)

func printMyName(name: String) -> Void {
    print(name)
}

func printYourName(name: String) {
    print(name)
} // 리턴이 없을 경우 반환 타입(void)을 생략해 줄 수 있음

매개변수가 없는 함수

func 함수이름() -> 반환타입 {
    return 반환값
}

ex)

func maximumIntegerValue() -> Int {
    return Int.max
}

매개변수와 반환값이 없는 함수

func 함수이름() -> Void {
    return
}

ex)

func hello() -> Void { print("hello") }
// 반환 값이 없는 경우, 반환 타입(Void) 생략가능

func 함수이름() {
    return
}
func bye() { print("bye") }

함수의 호출

sum(a: 3, b: 5) // 8
printMyName(name: "dongle") // dongle
printYourName(name: "maple") // maple
maximumIntegerValue() // Int의 최댓값
hello() // hello
bye() // bye

매개변수 기본 값

매개변수에는 기본적으로 전달될 값을 미리 지정할 수 있습니다.
이때, 기본값을 갖는 매개변수는 매개변수 목록 중에 뒷쪽에 위치하는 것이 좋습니다.

func 함수이름(매개변수1이름: 매개변수1타입, 매개변수2이름: 매개변수2타입 = 매개변수 기본값 ...) -> 반환타입 {
    return 반환값
}

ex)

func greeting(friend: String, me: String = "dongle") {
    print("Hello \(friend)! I'm \(me)")
}

// 매개변수 기본값을 가지는 매개변수는 호출시 생략할 수 있습니다
greeting(friend: "maple") // Hello hana! I'm dongle
greeting(friend: "john", me: "eric") // Hello john! I'm eric

전달인자 레이블

함수를 호출 할 때 함수 사용자의 입장에서 매개변수의 역할을 좀 더 명확하게 표현하고자 할 때 사용

func 함수이름(전달인자 레이블 매개변수1이름: 매개변수1타입, 전달인자 레이블 매개변수2이름: 매개변수2타입 ...) -> 반환타입 {
    return
}

ex)

func greeting(to friend: String, from me: String) {
    print("Hello \(friend)! I'm \(me)")
}
// 호출
greeting(to: "hana", from: "dongle") // Hello hana! I'm yagom

가변 매개변수

전달 받을 값의 개수를 알기 어려울 때 사용

func 함수이름(매개변수1이름: 매개변수1타입, 전달인자 레이블 매개변수2이름: 매개변수2타입...) -> 반환타입 {
    return
}

ex)

func sayHelloToFriends(me: String, friends: String...) -> String {
    return "Hello \(friends)! I'm \(me)!"
}
print(sayHelloToFriends(me: "dongle", friends: "hana", "eric", "wing"))
// Hello ["hana", "eric", "wing"]! I'm dongle!

print(sayHelloToFriends(me: "dongle"))
// Hello []! I'm dongle!

데이터 타입으로서의 함수

스위프트의 함수는 일급객체입니다. 그래서 함수를 변수, 상수 등에 할당이 가능하고 매개 변수를 통해 전달할 수 있습니다.
함수의 타입표현

  • 변환타입 생략 할 수 없음

함수타입 사용

var someFunction: (String, String) -> Void = greeting(to:from:)
someFunction("maple", "dongle") // Hello maple! I'm dongle

someFunction = greeting(friend:me:)
someFunction("maple", "dongle") // Hello maple! I'm dongle


// 타입이 다른 함수는 할당할 수 없습니다 - 컴파일 오류 발생
//someFunction = sayHelloToFriends(me: friends:)


func runAnother(function: (String, String) -> Void) {
    function("jenny", "mike")
}

// Hello jenny! I'm mike
runAnother(function: greeting(friend:me:))

// Hello jenny! I'm mike
runAnother(function: someFunction)

퀴즈
다음 중 오류가 발생하는 코드를 고르세요

func addOne(left a: Int, right b: Int) -> Int {
  return a + b
}

func addTwo(a: Int = 0, b: Int = 0) -> Int {
  return a + b
}

답 : addOne(a: 10, b: 20)
외부 매개변수 사용해야함

제어문

조건문

if-else 구문
기본 형태

if 조건 {
    /* 실행 구문 */
} else if 조건 {
    /* 실행 구문 */
} else {
    /* 실행 구문 */
}

사용

let someInteger = 100

if someInteger < 100 {
    print("100 미만")
} else if someInteger > 100 {
    print("100 초과")
} else {
    print("100")
} // 100
  • 스위프트 조건에는 항상 Bool 타입이 들어와야함
  • someInteger는 Bool 타입이 아닌 Int타입이라 if someInteger {} 로 했을 경우 오류 발생

switch 구문

기본 형태

switch 비교값 {
case 패턴:
    /* 실행 구문 */
default:
    /* 실행 구문 */
}

사용법

// 범위 연산자를 활용하면 더욱 쉽고 유용합니다
switch someInteger {
case 0:
    print("zero")
case 1..<100:
    print("1~99")
case 100:
    print("100")
case 101...Int.max:
    print("over 100")
default:
    print("unknown")
} // 100

// 정수 외의 대부분의 기본 타입을 사용할 수 있습니다
switch "dongle" {
case "jake":
    print("jake")
case "mina":
    print("mina")
case "yagom":
    print("yagom!!")
default:
    print("unknown")
} // dongle!!
  • 범위 연산자를 활용하면 더욱 쉽고 유용합니다
  • 정수 외의 대부분의 기본 타입을 사용할 수 있습니다

반복문

for in 구문

기본 형태

for item in items {
    /* 실행 구문 */
}

사용법

var integers = [1, 2, 3]
let people = ["donle": 10, "eric": 15, "mike": 12]

for integer in integers {
    print(integer)
}

// Dictionary의 item은 key와 value로 구성된 튜플 타입
for (name, age) in people {
    print("\(name): \(age)")
}

while문

기본 형태

while 조건 {
    /* 실행 구문 */
}

사용법

while integers.count > 1 { // 조건에 해당되면
    integers.removeLast() // 수행
}

repeat-while 구문

기본 형태

repeat {
    /* 실행 구문 */
} while 조건

사용법

repeat {
    integers.removeLast()
} while integers.count > 0

퀴즈

  1. 다음 코드의 실행 결과로 콘솔에 출력될 문자열을 입력해주세요
let someInteger = 50

if someInteger < 100 {
    print("100 미만")
} else if someInteger > 0 {
    print("0 초과")
} else if someInteger > 30 {
    print("30 초과")
} else {
    print("50")
} 

답 : 100 미만

  1. 다음 코드의 실행 결과로 콘솔에 출력될 문자열로 알맞은 것을 고르세요
let someInteger = 50

case 0:
  print("zero")
case 1..<100:
  print("1~99")
case 50:
  print("50")
} 

답 : 실행불가 - 실행 조건에 someInteger가 들어가 있지 않으므로

  1. 다음 코드의 실행 결과로 콘솔에 출력될 내용을 고르세요
let max = 1
var count = 0

repeat {
    count = count + 1
    print(count)
} while count < max

답 : 1 - 1증가 후 print(), 후에는 max보다 작지 않음으로 반복문 탈출

Optional

기본 형태

let optionalValue: Int? = nil

?나 !를 붙여서 옵셔널을 만들어줄 수 있으며, 값이 없다는 뜻인 nil을 넣어줄 수 있다.

! 옵셔널

암시적 추출 옵셔널
기본 형태

let optionalValue: Int! = 100

사용

let optionalValue: Int! = 100

// 기존 변수처럼 사용 가능
optionalVlaue = optionalValue + 1

// nil 할당 가능
optionalVlaue = nil

// 잘못된 접근으로 인한 런타임 오류 발생
optionalVlaue = optionalValue + 1
// nil을 할당 후 다시 접근하려고 했기 때문

? 옵셔널

기본형태

let optionalValue: Int? = nil

사용

let optionalValue: Int? = 100

// nil 할당 가능
optionalVlaue = nil

// 기존 변수처럼 사용 불가
optionalVlaue = optionalValue + 1

Optional Unwrapping (옵셔널 추출)

Optinal Binding

옵셔널 값을 꺼대오는 방법 중 하나로 nil 여부 체크를 통해 안전한 값을 추출할 수 있음

Optional은 어떤 값이 상자에 포장되어 있다고 생각하면 됨

func printName(_ name: String) {
	print(name)
}

var myName: String? = nil

printName(myName)
// 전달되는 값의 타입과 다르기 때문에 컴파일 오류 발생, String != Optional(String)

if-let 사용하기

func printName(_ name: String) {
	print(name)
}

var myName: String? = nil

if let name: String = myName {
	printName(name)
} else
	printName("myName == nil" )
}
// name 상수는 if-let 구문 내에서만 사용가능
// 상수 사용범위를 벗어났기 때문에 컴파일 오류 발생
printName(name)

여러개 반환하기

var myName: String? = "dongle"
var yourName: String? = nil

if let name: myName, let friend = yourName {
	print("\(name) and \(friend)")
} 
// yourName이 nil 이기 때문에 실행되지 않음

yourName = "isiki"

if let name = myName, let friend = yourName {
	print("\(name) and \(friend)")
} // dongle and isiki 

Force Unwrapping

옵셔널의 값을 강제로 추출

func printName(_ name: String) {
	print(name)
}

var myName: String? = "dongle"

printName(myName!) // dongle

myName = nil
print(myName!) // 값이 없으므로 런타임 오류

var yourNameL String! = nil // 선언할 때부터 언래핑
printName(yourName) // nil값이 전달되므로 런타임 오류 

퀴즈

  1. 다음 중 오류가 발생하는 코드를 고르세요
    답 :
let optionalFour: Int = nil

기본 Int 자료형에는 nil 값이 들어갈 수 없으므로 Optional 자료형으로 선언해주어야 함

  1. 다음 중 오류가 발생하는 코드를 모두 고르세요
var optionalA: Int? = nil
var optionalB: Int! = nil

답 :

optionalA = optionalB + 1

print(optionalB * 3)
  1. 다음 코드의 [빈칸]에 알맞은 코드를 고르세요
let some: Int? = 100

[빈칸] unwrapped: Int = some {
  print("추출된 some의 값은 \(unwrapped)입니다")
}

답 : if let

profile
개발자를 꿈꾸는 학생입니다!

0개의 댓글