함수란?
- 특정 작업을 수행하는 코드 블록을 의미합니다.
- 함수 정의부의 값을 매개변수, 호출시의 값을 아규먼트라고 부릅니다. 예컨대 ‘자판기 함수’ 가 있다고 가정해 봅시다. 자판기 함수는 동전을 넣으면 음료수를 돌려주게끔 정의되어 있습니다. 이렇게 정의되어 있는 부분에서 동전은 ‘매개변수’가 됩니다. 실제로 내가 자판기에 동전을 넣으면, 그것은 ‘전달인자’가 됩니다.
메서드란?
- 특정 클래스나 구조체, 열거형 내에서의 함수를 말합니다.
- 함수를 스위프트 클래스 내에 선언한다면 그것을 메서드라 부릅니다.
함수를 선언하는 방법
func<함수이름>(<매개변수이름>:매개변수타입, <매개변수이름>:<매개변수타입>,...) -> <반환값 타입>
{
//함수코드
}
로 선언합니다. 함수가 어떤 것도 반환하지 않으면, 반환값 타입과 -> 는 생략이 가능합니다.
func sqre(inteager: Int) -> Int{
return(inteager * inteager)
}
print(sqre(inteager:9)) // 함수를 호출, 81이 나옵니다.
매개변수를 제곱해서 리턴해주는 sqre라는 함수를 선언하고 호출했습니다. 다음은 C언어에서 두 개의 매개변수를 더해주는 add함수를 선언하고 호출하는 코드입니다.
#include <stdio.h>
int add(int x, int y)
{
return(x+y);
}
int main()
{
printf("%d",add(55,45)); //add() 함수를 호출했습니다.
}
이를 swift의 함수 호출식으로 바꾸어 보겠습니다.
func add(addnum1 x: Int, addnum2 y: Int) -> Int
{ // addnum1과 addnum2는 외부 매개변수명이고, x,y는 내부 매개변수명입니다.
return(x+y)
}
print(add(addnum1:55, addnum2:45))//함수를 호출할 때는 내부 매개변수명으로 호출합니다. 만약 외부 매개변수명을 생략하면 내부 매개변수명이 외부 매개변수명까지 겸할 수 있습니다.
print(type(of:add)) // add함수의 자료형은, (Int, Int) -> Int
아래의 예제를 살펴보겠습니다.
func add1(x: Int, y: Int) -> Int { // add함수 1
//외부매개변수명을 생략하면 내부매개변수명이 외부매개변수명까지 겸할 수 있습니다.
return(x+y)
}
print(type(of : add1))
func add2(first x: Int, second y: Int) -> Int{ //add함수 2
//first, second는 외부 매개변수명이며 호출할 때 사용합니다.
return (x+y)
}
print(type(of : add2))
func add3(_ x: Int, _ y: Int) -> Int{ //add함수 3
//_로 외부매개변수명을 생략할 수 있습니다.
return (x+y)
}
print(type(of : add3))
func add4(_ x: Int, with y: Int) -> Int{ //add함수 4
//첫 번째 외부매개변수명만 생략하는 경우가 많습니다.
return (x+y)
}
print(type(of : add4))
print(type(of:add(1/2/3/4))) 을 하면 각각 4개의 함수는 다 똑같은 결과가 나옵니다. 그러나 각각 함수의 이름은 다릅니다.
func add1(x: Int, y: Int) -> Int { // add함수 1
print(#function)
return(x+y)
}
add1(x:10,y:4)
func add2(first x: Int, second y: Int) -> Int{ //add함수 2
print(#function)
return (x+y)
}
add2(first:10, second:4)
func add3(_ x: Int, _ y: Int) -> Int{ //add함수 3
print(#function)
return (x+y)
}
add3(10,4)
func add4(_ x: Int, with y: Int) -> Int{ //add함수 4
print(#function)
return (x+y)
}
add4(_:10,with:4)
/*
각각의 결과입니다.
add1(x:y:)
add2(first:second:)
add3(_:_:)
add4(_:with:)
*/
각각의 결과는 다르게 나옵니다.
swift에서, 함수명이란 func다음단어(외부매개변수명:외부매개변수명:…)입니다.
swift에서, 함수자료형이란 (자료형, 자료형,…) -> 리턴형 입니다.
if~let 과 guard~let의 차이
func printName(firstName:String, lastName:String?){
if let lName = lastName{ //lastName이 nil이 아니라면?
print(lName,firstName)
}
else{
print("성이 없네요!")
}
}
printName(firstName: "길동", lastName:"홍")
printName(firstName: "길동", lastName:nil)
일단 printName(firstName:lastName:)
이라는 이름을 가지고 있는 함수를 만들었습니다. firstName
의 자료형은 String
, lastName
의 자료형은 옵셔널 String
이네요. nil값을 가질 수도 있고, 아닐 수도 있다는 의미입니다.
다음으로는 lastName
이 nil
값을 가지는지, 아닌지를 판단합니다. 만약 lastName이 nil값을 가지지 않는다면, print()문장을 수행할 것이고, 그렇지 않다면 else
"성이 없네요" 를 print 할 것입니다.
여기서, 이를 대체할 수 있는 guard문에 대하여 예제를 살펴보겠습니다.
func printName(firstName:String, lastName:String?){
guard let lName = lastName else {
print("성이 없네요!")
return
}
print(lName, firstName)
}
printName(firstName: "길동", lastName:"홍")
printName(firstName: "길동", lastName:nil)
guard문에서는 조건식이 거짓이면 실행됩니다. lastName이 nil값을 가질 경우(lastName이 nil값을 가지지 않는 것이 거짓일 경우) “성이 없네요!”를 print합니다.
함수로부터 여러개의 결과를 반환하는 방법
함수는 여러 결과값들을 튜플로 감싸서 반환할 수 있습니다.
func converter(kg: Float) -> (g: Float, mg: Float, lbs: Float) {
let g = kg * 1000
let mg = kg * 1000*1000
let lbs = kg * 2.20462
return (g, mg, lbs)
}
var resultTuple = converter(kg:500)
print(resultTuple) // 튜플의 값을 내보냅니다.
print(resultTuple.g) // 하나의 값만 지정해서 내보낼 수도 있습니다.
print(resultTuple.mg)
print(resultTuple.lbs)
아래는 2개의 정수를 입력받아 가감제로 리턴하는 함수입니다.코드를 보기 전에 자료형과 함수명을 추측해보세요.
import Foundation
func sss(x : Int, y : Int) -> (sum : Int, sub : Int, div : Double, rem : Int)
{
let sum = x+y //더하기
let sub = x-y //빼기
let div = Double(x)/Double(y) // 나누기
let rem = x % y // 나머지
print("function name : \(#function)")
return (sum, sub, div, rem) //리턴값
}
var result = sss(x:10289,y:31) // 함수 호출
print("function type : \(type(of:sss))")
print("sum : \(result.sum)") // 더하기 값에 접근
print("sub : \(result.sub)") // 빼기 값에 접근
print("div : \(String(format: "%.3f", result.div))") // 나누기를 세 번째 자리에서 반올림, 접근
print("rem : \(result.rem)") // 나머지 값에 접근
/*
function name : sss(x:y:)
function type : (Int, Int) -> (sum: Int, sub: Int, div: Double, rem: Int)
sum : 10320
sub : 10258
div : 331.903
rem : 28
*/
import Foundation 코드와 (String(format: “%.3f”, result.div) 를 이용해서, result.div 값을 소수점 세 자리에서 반올림하였습니다.함수의 이름과 자료형도 출력하게끔 하였습니다.
함수가 가변 매개변수를 받을 때
swift에서는 함수가 가변 매개변수를 받는다는 것을 가리키기 위해서 세 개의 점을 사용합니다. 아래의 예제를 살펴봅시다.
func displayStrings(strings: String...) /// 가변 매개변수를 받는다는 뜻입니다.
{
for string in strings {
print(string)
}
}
displayStrings(strings: "일", "이", "삼", "사")
displayStrings(strings: "one", "two")
임의의 개수의 정수 값의 합을 출력하는 함수를 작성해 봅시다.
func addInteagers(numbers: Int...)
{
var sum: Int = 0
for num in numbers{
sum = sum + num // sum에다가 sum + num의 값을 대입하는 것을 반복
}
print(sum)
}
addInteagers(numbers:1,2,5,5,5,3,12,3,5,6,7,4,4,5,67,7,4,2,34,54)
call by reference VS call by value
call by reference는 ‘참조에 의한 호출’ 입니다. 인자로 받은 값의 주소를 참조하여 직접 값에 영향을 준다는 특징이 있습니다.
call by value는 ‘값에 의한 호출’ 입니다. 인자로 받은 값을 복사하여 처리하기 때문에, 원래의 값이 보존된다는 특징이 있습니다.
var myValue = 10
func doubleValue (value: inout Int) -> Int { //call by reference 하고 싶은 매개변수의 자료형 앞에 inout을 씁니다.
value += value
return(value)
}
print("함수 호출 전 : \(myValue)")
print("함수 호출 : \(doubleValue(value : &myValue))")
print("함수 호출 후 : \(myValue)")
/*
함수 호출 전 : 10
함수 호출 : 20
함수 호출 후 : 20
*/
값의 주소를 참조하여 직접 값에 영향을 주기 때문에, 함수 호출 전과 후에 있어 myValue의 값에 차이가 있는 것을 볼 수 있습니다.
제가 이해한 swift 함수 정리입니다.