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)")
  • ํŽธํ• ๋•Œ๊ฐ€ ์žˆ๊ธด ํ•œ๋ฐ...
  • CustomStringConvertible ์„ ์จ๋„ ๋  ๊ฒƒ ๊ฐ™๊ธด ํ•˜๊ณ ...

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** โš ๏ธ