Swift 5.5 Release(5)

유재경·2021년 6월 16일

iOS New Release

목록 보기
5/12
post-thumbnail

(※ hackingWithSwift의 글을 번역한 것으로 아래 출처를 남겨두었습니다. 약간의 오역이 있을 수 있으니 지적해주시면 감사드리겠습니다.)

지역변수로서 lazy

lazy는 처음 사용할 때 계산되는 저장 프로퍼티에만 사용해왔다. 하지만 Swift 5.5부터는 함수 내에 local하게 lazy 속성을 사용할 수 있게 되었다.

func printGreeting(to: String) -> String {
    print("In printGreeting()")
    return "Hello, \(to)"
}

func lazyTest() {
    print("Before lazy")
    lazy var greeting = printGreeting(to: "Paul")
    print("After lazy")
    print(greeting)
}

lazyTest()

해당 코드를 실행해보면, 다음 순서로 출력된다.

Before lazy
After lazy
In printGreeting()
Hello, Paul

즉, print(greeting)이 등장할 때, printGreeting 함수를 작동시킨다. 이것은 우리가 선택적으로 조건에 따라 코드를 실행하는데 유용할 것으로 보인다. 예를 들면 lazy하게 어떤 작업의 결과를 준비하거나, 나중에 필요하게 될 때 실행하는 작업들이 있다.

Property Wrapper 확장

함수와 클로저에 파라미터를 적용할 수 있도록 property wrapper를 확장했다. 이제 이 방식으로 전달된 파라미터들은 우리가 파라미터를 복사하지 않는 한 immutable(불변)하다.

우리가 0...100 범위 내의 값만 원한다면 다음처럼 property wrapper를 설정할 수 있다.

@propertyWrapper
struct Clamped<T: Comparable> {
    let wrappedValue: T

    init(wrappedValue: T, range: ClosedRange<T>) {
        self.wrappedValue = min(max(wrappedValue, range.lowerBound), range.upperBound)
    }
}

func setScore2(@Clamped(range: 0...100) to score: Int) {
    print("Setting score to \(score)")
}

setScore2(to: 50)
setScore2(to: -50)
setScore2(to: 500)

----------------------
50
0
500

Tip: 함수의 전달인자가 불변하기 때문에 위에 property wrapper는 아주 간단한 예시지만, 다른 프로퍼티나 지역변수와 결합해서 더 복잡하게 만들 수 있다.

generic에서 동적 멤버 조회

generic 함수 안에 프로토콜의 멤버를 위해 동적 멤버 조회를 허용한다(말이 어렵지만 예시를 보니 바로 이해가 가네요!) SwiftUI에서 사소하지만 가독성에 중요한 영향을 미쳤다.

Toggle("Example", isOn: .constant(true))
    .toggleStyle(SwitchToggleStyle())

( SwiftUI에서 이렇게 쓰던 것을 좀 더 UIKit스럽게 바꾼 느낌이네요! )

Toggle("Example", isOn: .constant(true))
   .toggleStyle(.switch)

원래 SwiftUI 베타 버전에서는 이게 가능했었는데 배포 이후에 뺐다. Protocol의 경우도 살펴보면 이렇다.

protocol Theme { }
struct LightTheme: Theme { }
struct DarkTheme: Theme { }
struct RainbowTheme: Theme { }

protocol Screen { }

extension Screen {
    func theme<T: Theme>(_ style: T) -> Screen {
        print("Activating new theme!")
        return self
    }
}

struct HomeScreen: Screen { }

let lightScreen = HomeScreen().theme(LightTheme())

lightScreen을 이런 식으로 매번 LightTheme을 정의했던 것에서 정적 프로퍼티인 light를 추가하면 더욱 편리하게 쓸 수 있다는 것이다.

extension Theme where Self == LightTheme {
    static var light: LightTheme { .init() }
}

let lightTheme = HomeScreen().theme(.light)

이번에는 프로퍼티에 대한 글이 많았습니다. Swift 5.5에 대한 포스팅은 여기서 마치는데 이 외에도 여러가지가 있는 것 같더라고요 공식문서를 참조해주세요!

(출처 https://www.hackingwithswift.com/articles/233/whats-new-in-swift-5-5)

profile
iOS 개발

0개의 댓글