swift 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
댓글남기기