swift 3(함수, 옵셔널)

3 분 소요

2020.03.18

‘야곰. 스위프트 프로그래밍 3판. 한빛미디어’를 바탕으로 작성되었습니다.

7장 함수

  • overriding, overloading을 모두 지원합니다.

기본 구조

func hello(name: String) -> String {
    return "Hello \(name)";
}

func hello(name1: String, name2: String) -> String {
    "Hello \(name1) and \(name2)";              // return을 제외하고 내부코드가 없을 경우 return 키워드는 생략 가능
}

print(hello(name: "Philip"));                   // Hello Philip
print(hello(name1: "Alice", name2: "Bob"));     // Hello Alice and Bob

전달인자 레이블

func hello(from name1:String, to name2:String) -> String {
    return "Hello \(name2). I'm \(name1)";
}

// 레이블 생략 가능합니다.
func hello(_ name1:String, _ name2:String) -> String {
    return "Hello \(name2). I'm \(name1)";
}

// 레이블이 다르면 오버로딩 합니다.
func hello(from name1:String, toto name2:String) -> String {
    return "Hello \(name2). I'm \(name1)";
}

print(hello(from: "Alice", to: "Bob"));         // Hello Bob. I'm Alice
print(hello("Alice", "Bob"));
print(hello(from: "Alice", toto: "Bob")); 

가변 매개변수

  • 가변 매개변수로 들어온 인자는 배열처럼 사용할 수 있습니다.
  • 함수마다 1개의 가변 매개변수를 가질 수 있습니다.
func hello(name1: String, other names: String...) -> String {
    var result: String = "I'm \(name1). Hello ";

    for name in names {
        result += "\(name), ";
    }
    return result;
}

print(hello(name1: "Philip", other: "Alice", "Bob"));

입출력 매개변수

  • inout 키워드를 이용해서 C 언어의 포인터와 유사한 기능을 할 수 있습니다.
func swap(left: inout Int, right: inout Int){
    var tmp: Int = left;
    left = right;
    right = left;
}

var a: Int = 10;
var b: Int = 20;

print("a : \(a), b : \(b)");        // a : 10, b : 20
swap(&a, &b);
print("a : \(a), b : \(b)");        // a : 20, b : 10

데이터 타입(함수)

typealias CalcIntInt = (Int, Int) -> Int

func addIntInt(_ a: Int, _ b: Int) -> Int {
    return a + b;
}

var myFunc: CalcIntInt = addIntInt;

print(myFunc(1, 2));        // 3

중첩 함수

typealias MoveFunc = (Int) -> Int

func selectFunc(_ isPositive: Bool) -> MoveFunc {
    func plus(_ num: Int) -> Int {
        return num + 1;
    }

    func minus(_ num: Int) -> Int {
        return num - 1;
    }

    return isPositive ? minus : plus;
}

var num: Int = -4;
let moveToZero: MoveFunc = selectFunc(num >= 0);

while num != 0 {
    print("num : \(num)");
    num = moveToZero(num);
}
print("num : \(num)");

Nonreturning function (비반환 함수)

  • 비반환 함수의 return type은 Never 입니다.
func customException() -> Never {
    fatalError("Something error");
}

func someFunc(isActiveWell: Bool) {
    guard isActiveWell else{            // guard 관련 설명은 추후에 작성하겠습니다.
        print("someFunc error");
        customException();
    }
    print("someFunc active well");
}

someFunc(isActiveWell: true);
someFunc(isActiveWell: false);

return 값을 사용하지 않는 함수

  • 가끔 return 값을 사용하지 않아도 상관없는 함수가 있습니다. (ex. chain-rule을 적용한 setter)
  • @discardableResult를 선언해서 경고를 무시합니다.
func hello(name: String) -> String {
    print("name : \(name)");
    return "name : \(name)";
}

@discardableResult func discardableResultHello(name: String) -> String {
    print("name : \(name)");
    return "name : \(name)";
}

hello(name: "Philip");                      // 경고 발생
discardableResultHello(name: "Philip");     // 경고 무시

8장 옵셔널

  • 옵셔널 변수 또는 상수에만 nil 할당 가능
  • 옵셔널로 선언하고 싶다면 데이터 타입 뒤에 ?를 붙여줍니다.
  • 함수 전달인자의 값이 잘못된 경우 nil을 반환하는 것으로 오류를 알려줍니다.
  • 매개변수 타입을 옵셔널로 정의하여 굳이 넘기지 않아도 된다는 것을 알려줍니다.
  • 옵셔널은 제네릭이 적용된 열거형입니다.
func checkOptionalValue(_ optionalValue: String?) {
    switch optionalValue {
    case .none:
        print("nil");
    case .some(let value):
        print("\(value)");
    }
}

var myName: String? = "Philip";
checkOptionalValue(myName);

myName = nil;
checkOptionalValue(myName);

Optional Unwrapping

Forced Unwrapping

  • 옵셔널 값 뒤에 !를 붙여서 값을 강제로 추출합니다.
  • 값이 없다면 런타임 에러가 발생합니다.
var myName: String? = "Philip";
var yourName: String  = myName!;

myName = nil;
yourName = myName!;     // 런타임 에러

Optional Binding

  • 옵셔널에 값이 있는지 확인할 때 사용합니다.
  • 옵셔널 체이닝과 자주 함께 쓰입니다.
var myName: String? = "Philip";

if let yourName = myName {
    print(yourName);
} else {
    print("myName == nil");
}

Implicitly Unwrapped Optionals

  • 데이터 타입 뒤에 ?대신에 !를 붙여서 옵셔널이 아닌 변수/상수를 선언할 수 있습니다.
var optionalValue: String? = "Philip";
var ImplOptionalValue: String! = "Philip";

print(optionalValue);           // Optional("Philip")
print(ImplOptionalValue);       // Philip

카테고리:

업데이트:

댓글남기기