Swift 5 : 함수와 메소드

버들비·2020년 7월 14일
0

Swift

목록 보기
4/10

함수와 메서드의 차이

클래스 또는 구조체 내에서 선언된 함수는 메서드. 함수에 적용되는 규칙과 메서드에 적용되는 규칙은 같다.

매개변수와 인자의 차이

함수가 호출될 때 받게 되는 값을 매개변수라고 하고, 함수에 값이 전달된 시점에서는 인자라고 부른다.
(시간,위치)를 매개변수로 받는 함수가 있을때, (낮 열두시,서울)을 인자로 전달한다.

함수선언

func 함수명 (외부매개변수명 지역매개변수명 : 매개변수타입, 외부매개변수명 지역매개변수명 : 매개변수타입, ...) -> 반환결과 타입 {
	함수의 실행부분 코드
}
func buildMessageFor(name: String, count: Int) -> String {
	return "\(name), your number is \(count)"
    
}

이때 실행부분 코드가 단일 표현식이면(한줄로 표현되면) return 구문을 생략할 수 있다.
함수의 return 값이 필요없을 경우, 반환값을 _에 할당하여 버릴 수 있다.

_ = buildMessageFor(name: "John", count: 100)

지역 매개변수명(local parameter name)과 외부 매개변수명(external parameter name)

함수의 파라미터들은 각각 지역 매개변수명과 외부 매개변수명을 가진다. 파라미터명과 인자레이블(Argument Label)이라고도 한다. 인자레이블은 함수를 호출할때 사용된다. 외부 매개변수명을 생략한 경우, 암묵적으로 외부 매개변수명과 지역 매개변수명은 같은 것으로 본다.

func buildMessageFor(userName name: String, userCount count: Int) -> String {
	return "\(name), your number is \(count)"
}
let message = buildMessageFor(userName: "John", userCount: 100)

선언된 함수 내부에선 지역 매개변수명으로 작성되지만, 함수를 호출할때는 외부 매개변수명을 이용해 적어야 한다. 외부 매개변수명을 생략할 경우, 함수를 호출할때 지역 매개변수명으로 작성하면 된다.
언더바 _를 사용해 매개변수명을 생략하고 함수를 호출할 수 있다.

func buildMessageFor(_ name: String, count: Int) -> String {
	return "\(name), your number is \(count)"
}
let message = buildMessageFor("John", count: 100)

또한 매개변수에 default 값을 줄 수 있다. 디폴트 값은 언더바 _ 를 사용한다.

func buildMessageFor(_ name: String = "John", count: Int) -> String {
	return "\(name), your number is \(count)"
}
let message = buildMessageFor(count: 100)

함수 인자레이블과 파라미터명(Function Argument Labels and Parameter Names)

함수의 파라미터들은 각각 인자레이블과 파라미터명을 가진다. 인자레이블은 함수를 호출할때 사용된다.

여러 결과값 반환하기

결과값에 튜플을 이용한다.

func sizeConverter(_ length: Float) -> (yards: Float, centimeters: Float, meters: Float) {
	let yards = length * 0.0277778
    let centimeters = length * 2.54
    let meters = length * 0.0254
    
    return (yards, centimeters, meters)
}

함수가 반환하는 튜플은 튜플 사용법과 같다.

let lengthTuple = sizeConverter(20)
print(lengthTuple.yards) // yards 에 해당하는 값 출력

매개변수의 갯수가 불확실한 경우

점 세개 ... 를 이용한다. 함수내에서 매개변수는 배열 형태로 이용할 수 있다.

func printStrings(_ strings:String...) {
	for string in strings {
    	print(string)
    }
}
printStrings("one","two","three","four")

매개변수를 함수 내부에서 변경하고 싶은 경우

함수가 받는 모든 매개변수는 기본적으로 상수 취급. 함수가 받은 매개변수 값을 바꾸고 싶으면 섀도 카피를 만든 뒤 바꿔야 한다.

func sizeConverter(_ length: Float) -> (yards: Float) {
	var yards = yards
    yards = length * 0.0277778
    return yards
}
print(sizeConverter(10.0)) // 0.277778

입출력 매개변수

기본적으로 함수 내부에서 쓰인 매개변수는 함수바깥에 변화를 주지 않는다. myValue 라는 값을 전달받은 함수가, 전달받은 값을 2배로 한 뒤 반환한다 해도, 원본 값인 myValue 에는 변화가 없다.

var myValue = 10
func doubleValue(_ value : Int) -> Int {
	var value = value // 함수 내부에서 쓰기 위해 섀도카피 
    value = value * 2
    return value
}
print(myValue) // 10
print(doubleValue(myValue)) // 20
print(myValue) // 10

함수가 값을 반환한 뒤에도 매개변수에 대한 변경을 유지하려면, 함수 선언부에서 매개변수가 입출력 매개변수(inout parameter)라고 선언해야 한다. inout 키워드를 추가하고, 섀도카피를 하는 부분을 삭제한다. 함수를 호출할때는 매개변수 앞에 &를 붙여야 한다.

var myValue = 10

func doubleValue(_value : inout Int) -> Int {
	value = value * 2 
    return value
}

print(myValue) // 10
print(doubleValue(&myValue)) // 20
print(myValue) // 20

매개변수인 함수

swift에서는 함수를 데이터 타입처럼, 변수나 상수에 할당하는 것도 가능하다.

func doubleValue(_value : inout Int) -> Int {
	value = value * 2 
    return value
}

let doDouble = doubleValue
let result = doDouble(10) // result is 20

함수는 데이터 타입처럼, 다른 함수의 인자로 전달되거나 함수의 반환값으로 반환될 수 있다.
함수 데이터 타입은 받게 될 매개변수의 데이터 타입과 반환될 데이터 타입을 조합하여 결정된다.
만약 Float 을 받고 Float을 반환하는 함수가 있을 경우, 함수의 데이터 타입은 다음과 같다.

(Float) -> Float

Int 와 Double 을 받고 String 을 반환하는 함수의 데이터 타입은 다음과 같다.

(Int, Double) -> String

"Float 을 받고 Float을 반환하는 함수"를 받고 Float을 반환하는 함수는 다음과 같다.

func functionConverter(_ inputFunc : (Float) -> Float) -> Float {
	var output : Float = 1.5
    return output
}

Bool 값을 받고 "Float 을 받고 Float을 반환하는 함수"를 반환하는 함수는 다음과 같다.

func floatToFloat_1(_ input: Float) -> Float {
	// Float 을 반환
}
func floatToFloat_2(_ input: Float) -> Float {
	// Float을 반환
}

func testFunction(_ input : Bool) -> (Float) -> Float {
	if input {
    	return floatToFloat_1
    } else {
    	return floatToFloat_2
	} 
}    

0개의 댓글