이번 시간에는 Swift에서 쓰이는 guard let에 대해서 알아보고 예제 소스를 살펴보도록 하겠습니다.
guard~let
Swift에서 guard let은 옵셔널 값의 안전한 언래핑을 위해 사용되는 구문입니다. guard let 구문은 조건을 검사하고, 조건이 참일 경우에만 옵셔널 값을 안전하게 추출하여 사용할 수 있도록 합니다.
일반적으로 guard let 구문은 함수나 메서드 내부에서 사용되며, 함수 실행 중간에 예외적인 상황이 발생했을 때 조기에 종료하는 역할을 수행합니다.
guard는 return, break, continue, throw 등 제어문 전환 키워드를 쓸 수 있는 상황이라면 사용이 가능하며, 함수 뿐 아니라 반복문 등 특정 블록 내부에 있으면 사용 가능합니다. 물론 함수 내부에 있다면 보통 return을 써서 해당 함수를 조기에 빠져나오는 조기 출구 용도로 사용하게 됩니다.
실제로 앱을 만들다 보면 옵셔널 바인딩 때문에 다중 if ~ else를 사용해야 하는데, guard ~ let을 사용하면 다중 루프 없는 훨씬 가독성이 좋은 코드가 만들어지기 때문에 그런 경우에 많이 사용합니다.
다음은 guard let의 기본적인 문법입니다.
guard let unwrappedValue = optionalValue else {
// 옵셔널 값이 nil인 경우 실행될 코드
// 종료 또는 에러 처리 등의 작업 수행
return // 함수나 메서드를 종료하거나, 다른 흐름으로 이동
}
// unwrappedValue를 안전하게 사용할 수 있는 범위에서 실행될 코드
위의 코드에서 optionalValue는 옵셔널 타입의 변수 또는 상수입니다. 만약 optionalValue가 nil이 아니라면, 해당 값은 unwrappedValue로 안전하게 추출되어 그 아래의 코드 블록에서 사용할 수 있습니다. 그렇지 않으면 else 블록 내부가 실행되고, 일반적으로 함수나 메서드를 종료하거나 에러 처리 등을 수행합니다.
예를 들어, 다음은 숫자 문자열을 정수로 변환하는 함수에서 guard let을 사용한 예제입니다.
func convertToInt(string: String) -> Int? {
guard let intValue = Int(string) else {
print("유효하지 않은 숫자 문자열입니다.")
return nil
}
return intValue
}
let numberString = "123"
if let convertedNumber = convertToInt(string: numberString) {
print("숫자 변환 결과: \(convertedNumber)")
}
위의 예제에서 convertToInt() 함수는 문자열을 정수로 변환하여 반환합니다. 만약 입력된 문자열이 유효한 숫자 형식이 아니라면, Int() 초기화 과정에서 실패하여 intValue가 nil이 됩니다. 이때 guard 문장 내부가 실행되고 "유효하지 않은 숫자 문자열입니다."라는 메시지가 출력됩니다. 그렇지 않으면 반환된 정수 값을 변수에 할당하여 출력합니다.
따라서, guard let 구문은 옵셔널 값을 안전하게 추출하여 그 이후의 코드 블록에서 활용하기 위해 유용한 Swift 문법 중 하나입니다.
guard let~else로 옵셔널 바인딩
guard let 문은 Swift에서 옵셔널 바인딩을 수행하는 구문 중 하나입니다. 이를 사용하여 옵셔널 값이 존재하는지 확인하고, 값이 존재하지 않으면 조건을 만족하지 않는 상태를 처리할 수 있습니다.
guard let~else로 옵셔널 바인딩을 하는 예제를 살펴보겠습니다.
func multiplyByTen(value: Int?) {
guard let number = value else {//조건식이 거짓(nil)일 때 else 블록 실행
print("nil")
return
}
print(number*10) //조건식이 참일 때 실행, 주의 : number를 guard문 밖인 여기서도 사용 가능
}
multiplyByTen(value: 3) //30
multiplyByTen(value: nil)
multiplyByTen(value: 10)
위의 소스 코드는 multiplyByTen이라는 함수를 정의하고, 옵셔널 값을 받아 해당 값에 10을 곱한 결과를 출력하는 예제입니다.
함수 내부에서 guard let 구문을 사용하여 입력값인 value가 nil이 아닌지 확인합니다.
- 첫 번째 호출인 multiplyByTen(value: 3)에서는 입력값이 3으로 주어졌으므로 guard let 구문의 조건식이 참이 되어 else 블록은 실행되지 않습니다. 따라서, 입력값인 3에 10을 곱한 결과인 30이 출력됩니다.
- 두 번째 호출인 multiplyByTen(value: nil)에서는 입력값으로 nil이 주어졌으므로 guard let 구문의 조건식은 거짓입니다. 따라서, else 블록 내부의 코드가 실행되고 "nil"이 출력됩니다. 그 후에 return 문으로 함수가 종료됩니다.
- 세 번째 호출인 multiplyByTen(value: 10)에서는 입력값으로 10이 주어졌으므로 guard let 구문의 조건식은 참입니다. 따라서, 입력값인 10에 10을 곱한 결과인 100이 출력됩니다.
주목할 점은 guard 문 안에서 옵셔널 값을 추출하여 상수(number)에 할당했지만, 이 상수는 guard 문 밖에서도 사용할 수 있다는 것입니다. 즉, guard 문 안에서 옵셔널 바인딩된 값은 해당 스코프 내부 어디서든 접근 가능합니다.
디폴트 매개변수 정의
Swift에서는 함수나 메서드의 매개변수에 디폴트 아규먼트(Default Argument)를 지정하여 기본값을 설정할 수 있습니다. 이렇게 하면 함수를 호출할 때 해당 매개변수의 값을 생략하면 기본값이 사용됩니다.
디폴트 아규먼트를 정의하는 방법은 다음과 같습니다.
func greet(name: String = "World") {
print("Hello, \(name)!")
}
위 소스를 살펴보도록 하겠습니다.
위 소스에서 greet 함수는 name이라는 문자열 매개변수를 가지며, "World"라는 기본값이 할당되어 있습니다.
함수 호출 시 name 값을 제공하지 않으면 기본값인 "World"가 사용됩니다:
반면에 name 값을 제공하면 제공된 값이 사용됩니다.
기본값을 가진 매개변수는 필요에 따라 생략 가능하므로 코드 유연성을 높여줍니다. 또한, 이미 존재하는 함수에 새로운 매개변수를 추가하거나 인터페이스 호환성을 유지하면서 API 설계를 변경할 때 유용합니다.
함수 응용
함수로부터 여러 개의 결과 반환하기
Swift에서 함수는 여러 결과 값들을 튜플로 감싸서 반환할 수 있습니다. 소스 코드와 함께 살펴보도록 하겠습니다.
func converter(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)
}
var lengthTuple = converter(length:10)
print(lengthTuple)
print(lengthTuple.yards)
print(lengthTuple.centimeters)
print(lengthTuple.meters)
위의 코드는 converter라는 함수를 정의하고, 주어진 길이(length)를 야드(yards), 센티미터(centimeters), 미터(meters)로 변환하는 예제입니다. converter 함수는 주어진 길이(length)를 사용하여 야드, 센티미터, 미터 값을 계산하고 이들 값을 튜플로 반환합니다.
- yards: 입력된 길이(length)에 0.0277778을 곱하여 야드로 변환한 값입니다.
- centimeters: 입력된 길이(length)에 2.54를 곱하여 센티미터로 변환한 값입니다.
- meters: 입력된 길이(length)에 0.0254를 곱하여 미터로 변환한 값입니다.
함수가 반환하는 튜플은 (yards, centimeters, meters) 형태로 구성되어 있습니다.
다음으로, var lengthTuple = converter(length:10)라인에서는 converter 함수를 호출하고 반환되는 튜플 값을 lengthTuple 변수에 할당합니다. 이 때, 입력값으로 10을 전달하였으므로 해당 길이에 대한 야드, 센티미터 및 미터 값이 계산됩니다.
마지막으로 출력문인 print(lengthTuple), print(lengthTuple.yards), print(lengthTuple.centimeters)은 각각 전체 튜플 값을 출력하고 야드 값과 센티미터 값, 미터 값을 개별적으로 출력합니다.
2개의 정수를 입력 받아 가감제 리턴
import Foundation
func sss(x: Int, y: Int) -> (sum: Int, sub: Int, div: Double, mul: Int, rem: Int) {
let sum = x + y
let sub = x - y
let div = Double(x) / Double(y)
let mul = x * y
let rem = x % y
return (sum, sub, div, mul, rem)
}
var result = sss(x: 10, y: 3)
print(result.sum)
print(result.sub)
let formattedDiv = String(format: "%.3f", result.div)
print(formattedDiv)
print(result.mul)
print(result.rem)
감사합니다.
틀린 부분이 있거나 더 좋은 내용 훈수 환영합니다!
공감과 댓글 부탁드립니다.
'Apple > Swift' 카테고리의 다른 글
[Swift] 1급 객체 (first class object), 1급 시민 (first class citizen) (0) | 2023.10.13 |
---|---|
[Swift] 가변 매개변수, call by address 구현 (0) | 2023.10.12 |
[Swift] Raw Values (원시 값) (0) | 2023.10.10 |
[Swift] 델리게이트 패턴(Delegate Pattern) (2) | 2023.10.08 |
[Swift] 지연 저장 프로퍼티(Lazy Stored Properties) (0) | 2023.10.05 |