func 함수이름(매개변수1 이름 : 매개변수1 타입, 매개변수2 이름 : 매개변수2 타입 ... ) -> 반환타입
{
함수 구현부
return 반환값
}
func sum(a : Int, b : Int) -> Int
{
return a+b
}
func 함수이름(매개변수1 이름 : 매개변수1 타입, 매개변수2 이름 : 매개변수2 타입 ...) -> Void
{
함수 구현부
return
}
// 이렇게 해도 된다.
func 함수이름(매개변수 이름 : 매개변수 타입)
{
함수 구현부
return
}
func sayHello(name:String)
{
print("hello \(name)!")
}
func 함수이름() -> 반환타입
{
함수 구현부
return
}
func maximumIntegerValue() -> Int
{
return Int.max
}
sum(a:3, b:5) // 8
sayHello(name : "Lee") // hello Lee!
maximumIntegerValue() // Int의 최대값
func 함수이름(매개변수1 이름 : 매개변수1 타입, 매개변수2 이름 : 매개변수2 타입, 매개변수3 이름 : 매개변수3 타입 = 매개변수3 기본값 ...) -> 반환타입
{
함수구현부
return 반환값
}
func greeting(friend : String, me : String = "lee")
{
print("Hello \(frined)! i'm \(me)!")
}
greeting(friend : "eric", me : "lee") // Hello eric! i'm lee!
greeting(friend : "eric") // Hello eric! i'm lee!
func 함수이름 (전달인자 레이블 매개변수1 이름 : 매개변수1 타입, 전달인자 레이블 매개변수2 이름 : 매개변수2 타입...) -> 반환타입
{
함수 구현부
return 반환값
}
func greeting(to name : String, from me : String)
{
print("Hello \(name)! i'm \(me)!")
}
greeting(to : "hana", from : "lee") // Hello hana! i'm lee!
func 함수이름(매개변수1 이름 : 매개변수1 타입, 전달인자 레이블 매개변수2 이름 : 매개변수2 타입...) -> 반환타입
{
함수 구현부
return 반환값
}
func sayHelloToFriends(me : String, friends : String...) -> Void
{
return "Hello \(frineds)! i'm \(me)"
}
sayHelloToFriends(me : "lee" , friends : "eric","hana","son") // Hello ["eric","hana","son"]! i'm lee!
sayHelloToFrineds(me : "lee") // Hello []! i'm lee!
inout
을 통해 참조로 값을 전달할 수 있다. 이 때의 과정은 다음과 같다.
- 함수를 호출할 때, 전달 인자의 값을 복사한다.
- 해당 전달인자의 값을 변경하면, 함수 내에서 복사한 값을 변경한다.
- 함수를 반환하는 시점에 2에서 복사한 값을 원래의 매개변수에 할당한다.
var numbers: [Int] = [1,2,3]
func nonR(_ arr: [Int]){
var copyA: [Int] = arr
copyA[2] = 1
}
func yesR(_ arr: inout [Int]){
arr[2] = 1
}
nonR(numbers)
print(numbers)
yesR(&numbers)
print(numbers)
입출력 매개변수 사용시 주의할 점은 다음과 같다.
- 입출력 매개변수는 매개변수 기본값을 가질 수 없다.
- 입출력 매개변수는 가변 매개변수를 가질 수 없다.
- 입출력 매개변수는 상수를 인자로 전달할 수 없다.
var someFunc : (String, String) -> Void = greeting(to:from:)
someFunc("eric","lee") // Hello eric! i'm lee!
someFunc = greeting(friend:me:)
someFunc("eric","lee") // Hello eric! i'm lee!
//타입이 다른 함수는 할당할 수 없다.
someFunc = sayHelloToFriend(me:friends:) // 컴파일 에러, 가변 매개변수를 갖는 함수이기 때문에 타입이 다르다.
func runAnother(function : (String, String) -> Void)
{
fuction("jenny", "mike")
}
runAnother(fuction:greeting(friend:me:)) // Hello Jenny! i'm mike!
runAnother(fuction:someFunc) // Hello Jenny! i'm mike!
var pos = 3
typealias moveFuction = (Int) -> Int
func functionForMove(_ shouldGoLeft: Bool)-> moveFuction
{
func goLeft(_ curPosition: Int) -> Int{
curPosition - 1
}
func goRight(_ curPosition: Int) -> Int{
curPosition + 1
}
return shouldGoLeft ? goLeft : goRight
}
let moveToZero: moveFuction = functionForMove(pos > 0)
while pos != 0 {
print("pos : \(pos)....")
pos = moveToZero(pos)
}
print()
함수의 구현부는 다음과 같이 되어있다.
public func print(_ items: Swift.Any...., seperator: String = default, terminator: String = default)
로 정의되어 있다. items 매개변수에 문자열이 할당이 되고 terminator 매개변수에는 기본적으로 '\n'
가 할당되어 있기 때문에, 개행이 되는 방식이다. 따라서 terminator: ""
를 통해 개행을 하지 않거나, terminator: " "
를 전달해 띄어쓰기를 하는 방법이 있다.
스위프트에는 종료되지 않는 함수를 정의할 수 있다. 이는 함수가 정상적으로 끝나지 않는 다는 의미로, 프로그램 오류 발생을 시킨다. Never
를 반환타입으로 한다면 종료되지 않는 함수를 정의할 수 있다.
func crashAndBurn() -> Never{
fatalError("something is wrong")
}
crashAndBurn()
func someFunction(isAllIsWell: Bool){
guard isAllIsWell else{
print("집에 도둑이 들었습니다.")
crashAndBurn()
}
print("AllisWell")
}
someFuction(isAllIsWell: true) // AllisWell
someFuction(isAllIsWell: false) // 집에 도둑이 들었습니다 및 프로세스 종료
Never
타입이 반환되는 대표적인 함수로는 fatalError
함수가 있다.
함수가 값을 반환함에도 불구하고 프로그래머가 의도적으로 반환값을 사용하지 않는 경우가 존재한다. 이때 @discardableResult
속성을 이용해 함수를 정의하면 컴파일러의 경고를 받지 않을 수 있다.
func say(_ something: String) -> String{
print(something)
return something
}
@discardableResult func discardableResultFunc(_ something: String) -> String{
print(something)
return(something)
}
say("hello") // 컴파일러가 경고를 표시할 수도 있음
discardableResultFunc("hello") // 컴파일러가 경고를 표시하지 않는다.