Share
Embed
Transcript
52 slides
-
What Will be changed in Swiftɹ v4.0.0(2) Daiki Matsudate /
@d_date SwiftѪձ vol.18 -
ࣗݾհ / Self Introduction ɾFreelance Engineer (2017/05ʙ) ɾ@d_date (Ͱ͌ʔͩͯ/Ͱ͌ʔͰ͍ͱ) ɾiOSྺ6
(iOS 4ʙ) ɾDaiki Matsudate ɾ6݄ʹαϯϊθʹߦ͖·͢✈ -
Manifest • ABIStability Manifesto • Generics Manifesto • Ownership Manifesto
• String Manifesto -
•ϥϕϧίϯετϥΫλ໊ͷҰ෦ Expr.elet(locals: [], body: anExpr) // ⭕, Swift 3ͷํ๏ Expr.elet(locals:
body:)([], anExpr) // ⭕, Swift 4͔ΒՄೳ // f(x: y:)(0, 0)ͱಉ͡ Expr.elet(locals: body:)(locals: 0, body: 0) // ❌ enum Expr { indirect case elet(locals: [(String, Expr)], body: Expr) } -
•ϥϕϧλϓϧͷҰ෦Ͱͳ͍ enum Expr { indirect case elet(locals: [(String, Expr)], body:
Expr) } let f = Expr.elet //([(String,Expr)],Expr) -> Expr f([], anExpr) // ⭕ f(locals: [], body: anExpr) // ❌ มʹ֨ೲ͢Δͱɺϥϕϧͷใ͕ফ͑Δ -
enum SyntaxTree { case type(variables: [TypeVariable]) case type(instantiated: [Type]) }
case .type // ❌: ᐆດ case .type(variables: let variables) // ⭕:ϑϧωʔϜΛࢦఆ͢Δ • ڞ௨ͷϕʔεωʔϜΛ͑Δ -
enum Animation { case fadeIn(duration: TimeInterval = 0.3) // ⭕
} let anim = Animation.fadeIn() // ⭕ • Associated ValueʹσϑΥϧτΛઃఆͰ͖Δ -
enum Tree { case leaf() // (()) -> Tree }
enum Tree { case leaf(Void) } •ۭͷλϓϧࢦఆͰ͖ͳ͘ͳͬͨ • Swift 4͔Β❌ • ্ͱಉ͜͡ͱΛΔʹɺVoidΛॻ͘ -
case .variable(name: let x) // ⭕ case .variable(x: let x)
// ❌: `x`ͱ͍͏ϥϕϧͳ͍ case .lambda(parameters: let params, body: let body) // ⭕ case .lambda(params: let params, body: let body) // ❌: ୈҰҾϥϕϧ͕ؒҧ͍ͬͯΔ •ύλʔϯͷҰ؏ੑ indirect enum Expr { case variable(name: String) case lambda(parameters: [String], body: Expr) } ϥϕϧ໊౷Ұ͢Δඞཁ͕͋Δ -
case .variable(let name) // ⭕: ม໊͕ϥϕϧ໊ͱಉ͡ case .lambda(let parameters, let
body) // ⭕: ม໊͕ϥϕϧ໊ͱಉ͡ case .variable(let x) // ❌: ϥϕϧͷॻ͖ํ1௨Γʹ౷Ұ͢Δඞཁ͕͋Δɻ case .lambda(let params, let body) // ❌: ্هͱಉ༷ case .lambda(parameters: let params, let body) // ❌ •ύλʔϯͷҰ؏ੑ indirect enum Expr { case variable(name: String) case lambda(parameters: [String], body: Expr) } ϥϕϧ໊ͱม໊͕ಉҰͷ࣌ʹݶΓɺϥϕϧΛ লུՄ -
[SE-0161] Smart KeyPaths: Better Key-Value Coding for Swift Accepted class
Person { var name: String var friends: [Person] = [] var bestFriend: Person? = nil init(name: String) { self.name = name } } var han = Person(name: "Han Solo") var luke = Person(name: "Luke Skywalker") luke.friends.append(han) -
[SE-0161] Smart KeyPaths: Better Key-Value Coding for Swift Accepted //
create a key path and use it let firstFriendsNameKeyPath = \Person.friends[0].name let firstFriend = luke[keyPath: firstFriendsNameKeyPath] // "Han Solo" // or equivalently, with type inferred from context luke[keyPath: \.friends[0].name] // "Han Solo" // rename Luke's first friend luke[keyPath: firstFriendsNameKeyPath] = "A Disreputable Smuggler" // optional properties work too let bestFriendsNameKeyPath = \Person.bestFriend?.name let bestFriendsName = luke[keyPath: bestFriendsNameKeyPath] // nil, if he is the last Jedi \Λ͚ͭΔ͜ͱͰɺKeyPathͱͯ͠͏͜ͱ͕Ͱ͖Δ -
[SE-0163] String Revision: Collection Conformance, C Interop, Transcoding • StringΛBidirectionalCollection,
RangeReplaceableCollectionͷద߹ • String.SubSequenceΛSubstringܕͱ͢Δ • Unicodeϓϩτίϧͷಋೖ • C interop ϝιουͷ౷߹ • Transcoding Infrastructure ͷվగ •มߋޙ -
[SE-0167] Swift Encoders •Ճޙ 1. JSON / Property ListͷDecoder/EncoderͷՃ 2.
NSKeyedArchiver/NSKeyedUnarchiverʹ CodableܕΛαϙʔτ -
CodableܕͱɺJSON Encoder/DecoderΛΈ߹ΘͤΔ let farm = Farm(name: "Old MacDonald's Farm", location:
Location(latitude: 51.621648, longitude: 0.269273), animals: [.chicken, .dog, .cow, .turkey, .dog, .chicken, .cow, .turkey, .dog]) let payload: Data = try JSONEncoder().encode(farm) do { let farm = try JSONDecoder().decode(Farm.self, from: payload) // Extracted as user types: let coordinates = "\(farm.location.latitude, farm.location.longitude)" } catch { // Encountered error during deserialization } -
[SE-0168] Multi-Line String Literals “””τϦϓϧΫΥʔτ”””Λ͏͜ͱͰɺෳߦͷString Λ͏͜ͱ͕Ͱ͖ɺ”ͷΤεέʔϓ͕ඞཁͳ͘ͳΔ assert( xml == """
<?xml version="1.0"?> <catalog> <book id="bk101" empty=""> <author>\(author)</author> <title>XML Developer's Guide</title> <genre>Computer</genre> <price>44.95</price> <publish_date>2000-10-01</publish_date> <description>An in-depth look at creating applications with XML.</description> </book> </catalog> """ ) -
[SE-0169] privateͱextensionͷ૬ޓ࡞༻ͷվળ •privateଐੑͰɺextensionΛ·͍ͨͰͷΞΫηε͕Մೳ struct S { private var p: Int
func f() { use(g()) // ⭕:extensionʹએݴ͞Ε͍ͯΔg()ʹΞΫηεՄೳ } } extension S { private func g() { use(p) // ⭕:SͷextensionͳͷͰɺpʹΞΫηεͰ͖Δ } } extension S { func h() { use(g()) // ⭕:h()g()ʹΞΫηεͰ͖Δɻ } } -
// FileA.swift struct A { private var aMember : Int
} // FileB.swift extension A { private func foo() { bar() // ⭕, foo()bar()ΞΫηεͰ͖Δ } } extension A { private func bar() { aMember = 42 // ❌, privateϑΝΠϧΛ·͍ͨͰͷΞΫηεෆՄ } } •privateʹϑΝΠϧΛ·͍ͨͰͷΞΫηεͰ͖ͳ͍ -
[SE-0171] Reduce with inout •Ճޙ extension Sequence { func reduce<A>(into
initial: A, _ combine: (inout A, Iterator.Element) - > ()) -> A { var result = initial for element in self { combine(&result, element) } return result } } inoutΛͬͨreduce͕Ճ͞ΕΔ -
[SE-0171] Reduce with inout extension Sequence where Iterator.Element: Equatable {
func uniq() -> [Iterator.Element] { return reduce(into: []) { (result: inout [Iterator.Element], element) in if result.last != element { result.append(element) } } } } ܭࢉྔ…O(n) •Ճޙ -
[SE-0171] Reduce with inout extension Sequence where Iterator.Element: Equatable {
func uniq() -> [Iterator.Element] { return reduce([]) { (result: [Iterator.Element], element) in guard result.last != element else { return result } return result + [element] } } } ܭࢉྔ…O(n2) •Ճલ -
[SE-0172] One-sided Ranges •มߋޙ let greeting = s.prefix(upTo: i) let
withComma = s.prefix(through: i) let location = s.suffix(from: i) ยଆͷΈͷrange operatorΛՃ let greeting = s[..<i]ɹ// ։۠ؒ let withComma = s[...i] // ด۠ؒ let location = s[i...] •มߋલ let greeting = s[s.startIndex..<i] //