지난주 주말, 토요일에 라인과 카카오 기업의 1차 코딩테스트 일정이 있었다. 아침 10시 ~ 오후 7시까지 풀로 코딩테스트 문제만 풀었다. Swift로 처음 코딩테스트 진행을 했는데 확실히 장단점이 큰 것 같다. 일요일에는 프로그래머스에서 과제테스트 예제 문제들을 풀어봤는데 Swift로 API 구성하는게 50줄 정도 나오는데 이게 맞는건가....ㅎ 하지만 화이팅!
1. 오전일정 : Swift 함수&메서드&클로저
1. 함수
- 함수는 특정 작업(다음에 또 써먹을 일 있는 작업)을 수행하기 위해 만들어진 코드 블록이다.
- 함수 호출 시에 받게 되는 값은 매개변수(Parameter)이고, 이 매개변수를 받아서 실제 함수가 호출되고 값이 전달된 시점에는 인자(Argument)라고 부른다. -> 매개변수와 인자라는 용어가 혼용되곤 하지만 미묘한 차이가 있다.
* y = f(x)에서 x는 매개변수, 이 매개변수에 실제 계산을 위하여 값 5,10을 넣으면 5,10은 인자라고 부른다.
2. 메서드 (함수랑 모양상으로 비슷하게 생김, 하지만...)
- 본질적으로 특정한 클래스, 구조체, 열거형과 관현된 함수이다. (모든 메서드는 함수이다.)
-> Swift 클래스, 구조체, 열거형 내에서 함수를 선언했다면 이것은 메서드로 간주된다. - 일반적으로 함수에 대해 설명하는 규칙과 동작 모두가 메서드에서도 동일하게 적용된다.
하다가 갑자기 Swift Playgound의 함수 파트 게임을 다시 시작하게 되었는데,,, 오늘은 간단하군요,, 오전 아주 조하 굿굿
2. 오후일정 : Swift 함수&메서드&클로저
<함수>
1. 함수를 선언하는 방법
//함수의 시그니처
func move(_ forward:Int) -> Int{
//함수 코드
return 10 //Int형 결과 반환 필요
}
- func = 함수라고 컴파일러에게 알려주기 위해 사용되는 키워드
- move = 함수명, 앱 코드 내에서 함수를 호출할 때 참조되는 이름
- forward = 함수 코드 내에서 참조할 매개변수 이름
* 만일 함수가 결과를 반환하지 않는다면 반환 결과 타입을 지정하지 않는다.
2. 단일 표현식에서의 암묵적 반환
- return 내용이 1줄이면 return 중괄호 생략
- 하지만 return을 꼭 명시해 주는 것이 더 좋다.
//원칙 코드
func exam(name:String, count:Int) -> String {
return "\(name, you are customer number \(count)"
}
// 단일 표현식 암묵적 반환
func exam(name:String, count:Int) -> String {
\(name, you are customer number \(count)
}
3. 지역 매개변수명, 외부 매개변수명
- 함수 안 : 지역(Local), 함수 밖 : 외부(external)
- 함수 안에서 사용하려는 매개변수명 : 지역 매개변수명
- 함수 호출 시 인자 전달을 위해 외부 매개변수명이 사용됨에도 함수 내에서 매개변수를 참조할 때는 여정히 지역 매개변수명이 사용된다.
아래에서 호출한 함수의 선언부를 보면 name와 count를 지역 매개변수이자 외부 매개변수명으로 사용한다고 선언했다.
let message = buildMessageFor(name:"John", count: 180)
매개변수에 할당된 디폴트 외부 매개변수명은 다음과 같이 지역 매개변수명 앞에 밑줄 문자를 써서 없앨 수 있다.
func buildMessageFor(name:String, count: Int) -> String {
return "\(name) \(count)"
}
func buildMessageFor(_ name:String, count: Int) -> String {
return "\(name) \(count)"
}
함수 선언부에서 지역 매개변수명 앞에 외부 매개변수명을 선언하면 사용이 가능하다.
userName, userCount가 외부 매개변수명이고, 이렇게 선언한 경우 함수 호출부에서 외부 매개변수명을 참조해야 한다.
func buildMessageFor(userName name:String, userCount count: Int) -> String {
return "\(name) \(count)"
}
let message = buildMessageFor(userName:"John", userCount: 180) //외부 매개변수명으로 호출
4. 함수의 디폴트 매개변수 선언
- Swift는 함수가 호출될 때 인자로 쓸 값이 들어오지 않는 경우에 사용할 디폴트 매개변수 값을 지정할 수 있다.
- 함수 선언 시 매개변수에 디폴트 값을 할당
인자로 고객 이름이 전달되지 않은 경우 디폴트 값을 넣도록 함수 변경
func buildMessageFor(name:String = "Customer", count: Int) -> String{
return "\(name) \(count)"
}
let message = buildMessageFor(Count: 180) //외부 매개변수명으로 호출
5. 여러 결괏값 반환
결괏값들을 튜플로 묶어주면 여러개의 결괏값을 함수가 반환할 수 있다.
func sizeConverter(length:Float) -> (yard:Float, centi:Float, meter:Float) {
let yard = length * 0.0277778
let centi = length * 2.54
let meter = length * 0.0254
return(yard, centi, meter)
}
let lengthTuple =sizeConverter(20)
print(lengthTuple.yard)
print(lengthTuple.centi)
print(lengthTuple.meter)
6. 가변개수 매개변수
- 앱 코드 내에서 함수가 호출될 때 함수가 받게 될 매개변수가 몇 개인지 알 수 없는 경우, Swift 가변 매개변수를 사용하여 처리 가능
- 함수가 지정된 데이터 타입의 매개변수 0개 또는 그 이상을 받는다는 것을 의미하는 점 3개(...)를 이용하여 가변개수 매개변수를 선언
- 함수 내에서 매개변수는 배열 개체의 형태로 사용할 수 있다.
func displayString(inputStrings:String){ //inputStrings가 String 타입이 아닌, Array<String>을 의미함
for string in inputStrings {
print(string}
}
}
displayString("One", "Two", "Three")
7. 변수인 매개변수
- 함수가 받는 모든 매개변수는 기본적으로 상수로 취급된다.
- 만약 함수 내에서 매개변수의 값을 변경하고 싶으면 섀도우 복사본을 생성해야 한다.
func calc(length: Float, width:Float) -> Float { //length, width는 상수이다.
var length = length
var width = width
return length * width
}
8. 입출력 매개변수로 작업하기
- 섀도우 복사본은 어떻게 변경한다고 해도 기본적으로는 원본 변수(실제로는 상수)에 반영되지 않는다.
- 함수가 값을 반환한 뒤에도 매개변수에 대한 변경을 유지하려면, 함수 선언부 내에서 매개변수를 입출력 매개변수(in-out parameter)로 선언해야 하고, 함수 호출입출력 매개변수 앞에 &를 붙여야 한다.
var myValue = 10
func doubleVaule(_ value:Int) -> Int {
var value = value
value += value
return value
}
print("Before = \(myValue)")
print("return = \(doubleValue(myValue))")
print("After = \(myValue)")
// 함수 안에서 myValue 자체를 건드는 코드
func doubleVaule(_ value:inout Int) -> Int {
value += value
}
print("Before = \(myValue)")
print("return = \(doubleValue(&myValue))") //&를 붙이지 않는다면 에러발생
print("After = \(myValue)")
9. 매개변수인 함수
- Swift에서는 함수가 데이터 타입(ex. Int, Float, String...)처럼 취급될 수 있다.
- 함수를 상수나 변수에 할당하는 것도 가능하다.
func starbucks(count: Int) -> String {
var count = count
return "스벅 아메리카노 \(count)잔"
}
func megacoffee(count: Int) -> String {
var count = count
return "메가커피 아메리카노 \(count)잔"
}
func twosome(count: Int) -> String {
var count = count
return "투썸 아메리카노 \(count)잔"
}
var order = starbucks
var result = order(10)
var order = megacoffee
var result = order(5)
var order = twosome
var result = order(8)
- 함수의 데이터 타입('들어오는 타입 -> 나가는 타입'으로 작성)은 받게 될 매개변수의 데이터 타입과 반환될 데이터 타입을 조합하여 결정된다.
func starbucks(count: Int) -> String {
var count = count
return "스벅 아메리카노 \(count)잔"
}
func megacoffee(count: Int) -> String {
var count = count
return "메가커피 아메리카노 \(count)잔"
}
func twosome(count: Int) -> String {
var count = count
return "투썸 아메리카노 \(count)잔"
}
var toCafe = starbucks
func order(_ cafe: (INT) -> String, value: Int) {
var result = cafe(value)
print("result is \(result)")
}
order(toCafe, value: 10)
- 불리언 매개변수의 값에 따라 함수 타입을 반환하도록 구성할 수 있다.
func starbucks(count: Int) -> String {
var count = count
return "스벅 아메리카노 \(count)잔"
}
func megacoffee(count: Int) -> String {
var count = count
return "메가커피 아메리카노 \(count)잔"
}
func twosome(count: Int) -> String {
var count = count
return "투썸 아메리카노 \(count)잔"
}
var toCafeA = starbucks
var toCafeB = megacoffee
var toCafeC = twosome
func decideCafe(_ cafe:Bool) -> (Int) -> String {
if A {
return toCafeA
} else if B {
return toCafeB
} else {
return toCafeC
}
}
<클로저 표현식>
- 클로저(closure)와 클로저 표현식(closure expression)은 혼용되어 불리지만, 몇가지 큰 차이점이 있다.
- 클로저 표현식은 독립적인 코드 블록이다.
- 아래 함수 내용을 첫줄에 1줄로 쓰는 것을 클로저 표현식이라고 한다.
//같은 함수
let sayhello = {print("Hello")}
sayHello()
//다른 정의 표현방식
func sayHello() {
print("Hello")
}
sayHello()
- 클로저 표현식은 매개변수를 받아 결괏값을 반환하도록 구성할 수도 있다.
- in 이 들어가면 클로저 표현식이 사용되었다고 생각하면 된다.
{(매개변수 이름: 매개변수 타입, 매개변수 이름: 매개변수 타입, .....) -> 반환결과 타입 in
//클로저 표현식의 코드
}
let multiply = {(val1: Int, val2: Int) -> Int in
return val1 * val2
}
let result = multifly(10,20)
func multiply(val1: Int, val2: Int) -> Int {
return val1 * val2
}
let result = multifly(10,20)
<오늘의 코딩 과제>
- 조원 이름 배열을 기반으로 작성하는 코드이기에 이름은 지우고 올립니다.
import Foundation
//코드1
func greetMessage(_ name:String) {
print("\(name)님 환영합니다.")
}
for popName in nameOfTeam11 {
greetMessage(popName)
}
//코드2
func greetMessage(_ nameArray:Array<String>){
for popName in nameArray {
print("\(popName)님 환영합니다.")
}
}
greetMessage(nameOfTeam11)
//코드3
func greetMessage(_ nameArray:Array<String>,_ index:Int){
let popName : String = nameArray[index]
print("\(popName)님 환영합니다.")
}
greetMessage(nameOfTeam11,4)
//코드4
func greetMessage(_ nameArray:Array<String>,_ index:Int) -> String{
return "\(nameArray[index])님 환영합니다."
}
print(greetMessage(nameOfTeam11,8))
//코드4 변형(함수 input에 들어오는 index값이 범위를 벗어날 경우 예외처리 코드로 업그레이드 시켜봄)
func greetMessage(_ nameArray:Array<String>,_ index:Int) -> String{
return nameArray.indices ~= index ? "\(nameArray[index])님 환영합니다." : "Out of range"
}
print(greetMessage(nameOfTeam11,7))
//코드5
func greetMessage(_ nameArray:Array<String>,_ index:Int) -> (String, Int){
return (nameArray[index], index)
}
let result = greetMessage(nameOfTeam11,4)
print("\(result.1)번에 위치하신 \(result.0)님 환영합니다")
//코드6
func greetMessage(_ names:String...){
for popName in names {
print("\(popName)님 환영합니다.")
}
}
greetMessage("키티", "쿠로미", "마이멜로")
*/
3. 오늘의 리뷰
함수.... 너무 힘들다... 클로저 표현식은 더 힘들다... 하지만 코딩문제 풀이는 잼있오 굿굿~~~ 코드 업그레이드 시키는 것도 재밌오 ㅎㅎ
'멋쟁이사자처럼 앱스쿨 1기' 카테고리의 다른 글
[멋쟁이사자처럼] 앱스쿨 1기 - 구조체(Struct)&Swift 컬렉션&property wrapper (12일차 22.09.29) (2) | 2022.09.30 |
---|---|
[멋쟁이사자처럼] 앱스쿨 1기 - 클래스&프로토콜 (10일차 22.09.27) (0) | 2022.09.27 |
[멋쟁이사자처럼] 앱스쿨 1기 - Playgorund 문제풀이&Swift 제어흐름 (8일차 22.09.23) (0) | 2022.09.23 |
[멋쟁이사자처럼] 앱스쿨 1기 - Playgorund 문제풀이&옵셔널 타입&Swift 연산자 (7일차 22.09.22) (0) | 2022.09.22 |
[멋쟁이사자처럼] 앱스쿨 1기 - 컴퓨터 기본지식&데이터타입 (6일차 22.09.21) (2) | 2022.09.21 |