Swift 5.0 Release - kirseia/study GitHub Wiki

Swift 5.0 릴리즈

Result Type

  • now
let result = Result { try String(contentsOfFile: someFile) } 
  • 이렇게 사용 가능, 결과를 Result로 감싸서 사용 가능
  • functional programming 할 때 error chaining 같을 때 유용하 것 같다.
  • Result 활용법

Raw Strings

  • before
print("<a href=\"\(url)\" title=\"Apple Developer\">")
  • now
print(#"<a href="\#(url)" title="Apple Developer">"#)
let answer = 42
let dontpanic = #"The answer to life, the universe, and everything is \#(answer)."#
  • escaping 을 안해도 된다는 장점은 있음. 특별한 상황에서 유용할 듯

Customizing string interpolation

  • now
struct User {
    var name: String
    var age: Int
}

extension String.StringInterpolation {
    mutating func appendInterpolation(_ value: User) {
        appendInterpolation("My name is \(value.name) and I'm \(value.age)")
    }
}

let user = User(name: "Guybrush Threepwood", age: 33)
print("User details: \(user)")

New BinaryInteger — isMultiple

  • before
// Swift:
7 % 2 == 1 // true
-7 % 2 == 1 // false. -7 % 2 evaluates to -1
// Ruby and Python
7 % 2 == 1 // true
-7 % 2 == 1 // true
  • now
let rowNumber = 4

if rowNumber.isMultiple(of: 2) {
    print("Even")
} else {
    print("Odd")
}
  • 음수일 때 문제가 있긴 했으나 ... 이것도 잘

count(where:)

  • xcode 10.2에서 제거 됐다고 함.

@dynamicCallable attribte

  • now
@dynamicCallable struct ToyCallable {
    func dynamicallyCall(withArguments: [Int]) {}
    func dynamicallyCall(withKeywordArguments: KeyValuePairs<String, Int>) {}
}

let x = ToyCallable()

x(1, 2, 3)
// Desugars to `x.dynamicallyCall(withArguments: [1, 2, 3])`

x(label: 1, 2)
// Desugars to `x.dynamicallyCall(withKeywordArguments: ["label": 1, "": 2])`
  • 잘 모르겠음
  • 유용하게 사용하는 코드를 봐야 알게 될 것 같음
  • 변수를 함수처럼 사용한다는데

본인을 참조하는 WritableKeyPath 추가

let id = \Int.self
var x = 2
print(x[keyPath: id]) // Prints "2"
x[keyPath: id] = 3
print(x[keyPath: id]) // Prints "3"
  • 전체 입력값 참조하는 KeyPath가 없었는데 (자신을 참조하는) .self KeyPath가 추가됨

enum 에 가변 변수 열거형 사용 불가

  • before
enum X {
    case foo(bar: Int...) 
}func baz() -> X {
    return .foo(bar: 0, 1, 2, 3) 
} 
  • now
enum X {
    case foo(bar: [Int]) 
}func baz() -> X {
    return .foo(bar: [0, 1, 2, 3]) 
} 
  • 의도되지 않았던 것이라 막았다고 함.
  • 대신 배열을 전달하는것이 가능해짐

Set, Dictionary 가 생성될 때 다른 seed를 가지게 됨

let a: Set<Int> = [1, 2, 3, 4, 5]
let b: Set<Int> = [1, 2, 3, 4, 5]
a == b  // true
print(a) // [1, 4, 3, 2, 5]
print(b) // [4, 2, 5, 1, 3]
  • 생성 될 때 원래 비슷했었나봄. 앞으로 생성 할 때 순서가 더 달라질거라고 함.

Sequence는 SubSequence Associated type을 갖지 않음.

The Sequence protocol no longer has a SubSequence associated type. Methods on Sequence that previously returned SubSequence now return concrete types. For example, suffix(_:) now returns an Array. (45761817)

  • 뭔지 잘 모르겠음.

컴파일 조건에 '<' 추가 됨

#if swift(<4.2)
// This will only be executed if the Swift version is less than 4.2.
#endif

#if compiler(<4.2)
// This will only be executed if the Swift compiler version is less than 4.2.
#endif
  • 기존에 >= 만 있었는데 유용할 것 같음

compactMapValues

  • before
let d: [String: String?] = ["a": "1", "b": nil, "c": "3"]
let r1 = d.filter { $0.value != nil }.mapValues { $0! }
let r2 = d.reduce(into: [String: String]()) { (result, item) in result[item.key] = item.value }
// r1 == r2 == ["a": "1", "c": "3"]
  • now
let d: [String: String?] = ["a": "1", "b": nil, "c": "3"]
let r4 = d.compactMapValues({$0})
// r4 == ["a": "1", "c": "3"]
  • 기존 array 에만 사용하던 compactValues가 dictionary 에도 추가 됨

Optional Try

// Swift 4: 'Int??'
// Swift 5: 'Int?'
let result = try? database?.countOfRows(matching: predicate)


// Swift 4: 'String??'
// Swift 5: 'String?'
let myString = try? String(data: someData, encoding: .utf8)
    
// Swift 4: '[String: Any]??'
// Swift 5: '[String: Any]?'
let dict = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
  • 기존에 optional 로 나오는게 2중 optional로 나와서 사용하기 귀찮았는데 좋아진 듯

No Async Await pattern (아직 도입 안 됨)

func processImageData(completionBlock: (result: Image) -> Void) {
   loadWebResource("dataprofile.txt") { dataResource in
      loadWebResource("imagedata.dat") { imageResource in
         decodeImage(dataResource, imageResource) { imageTmp in
            dewarpAndCleanupImage(imageTmp) { imageResult in
               completionBlock(imageResult)
             }
          }
       }
    }
}

이런 코드를 ->

func processImageData() async -> Image {
    let dataResource = await loadWebResource("dataprofile.txt")
    let imageResource = await loadWebResource("imagedata.dat")
    let imageTmp = await decodeImage(dataResource, imageResource)
    let imageResult = await dewarpAndCleanupImage(imageTmp)
    return imageResult
}
  • 이렇게 바꾸자는 논의가 있었으나 도입되지 않음.
  • funtional programming 과는 어울리지 않는 다는 이유 때문일까 ..?

String 기본이 UTF16 에서 UTF8로 바뀜

The String structure’s native encoding switched from UTF-16 to UTF-8, which may improve the relative performance of String.UTF8View compared to String.UTF16View. Consider re-evaluating any code specifically tuned to use String.UTF16View for performance. (42339222)

  • 속도 향상 약간 있다고 함

Ref.

⚠️ **GitHub.com Fallback** ⚠️