Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
Secret Swift tour
Yuka Ezura
March 01, 2018
Programming
7
2.1k
Secret Swift tour
2018/3/1
try! Swift Conference
Yuka Ezura
March 01, 2018
Tweet
Share
More Decks by Yuka Ezura
See All by Yuka Ezura
ezura
4
700
ezura
9
640
ezura
11
2.3k
ezura
3
1.1k
ezura
4
1.8k
ezura
5
510
ezura
1
520
ezura
1
760
ezura
2
740
Other Decks in Programming
See All in Programming
akkeylab
0
380
tommykw
1
380
mfunaki
1
510
akatsukinewgrad
0
230
yumcyawiz
5
670
dulltz
0
540
brunopulis
1
110
muttsu_623
0
560
mraible
PRO
0
320
kyoheig3
0
440
maito1201
0
550
yosuke_furukawa
PRO
14
4k
Featured
See All Featured
iamctodd
17
1.9k
tanoku
258
24k
jcasabona
7
520
andyhume
62
3.5k
keathley
18
650
frogandcode
127
20k
cassininazir
347
20k
dotmariusz
94
5.1k
philhawksworth
192
8.8k
zenorocha
296
40k
holman
288
130k
62gerente
587
200k
Transcript
Secret Swift tour 2018/3/1 try! Swift Conference Yuka Ezura
var myVariable = 42 myVariable = 50
let r = ( ) Void var myVariable = 42
myVariable = 50
obj?.myVariable = 50
(obj?.myVariable = 50) Optional<Void>
(obj?.myVariable = 50) .map { /* do something */ }
! error: Value of optional type 'Int?' not unwrapped; obj?.myVariable
+ 50
infix operator ⭐ func ⭐ (left: Int, right: Int) ->
Int { return left + right }aaaaaaa
! error: Value of optional type 'Int?' not unwrapped; obj?.myVariable
⭐ 5 infix operator ⭐ func ⭐ (left: Int, right: Int) -> Int { return left + right }aaaaaaa
infix operator ⭐ func ⭐ (left: Int, right: Int) ->
Int { return left + right }aaaaaaa
precedencegroup FoldedIntoOptionalChaining { assignment: true } :FoldedIntoOptionalChaining infix operator ⭐
func ⭐ (left: Int, right: Int) -> Int { return left + right }aaaaaaa
obj?.myVariable ⭐ 5 // => Optional<Int> 1 ⭐ 5 //
=> Int
let myVariable: Int = /* ?? */
let myVariable: Int = { while(true) {} }()
! error: Cannot convert value of type 'Never' to specified
type 'Int' let naver: Never = unsafeBitCast((), to: Never.self) let myVariable: Int = naver
let myVariable: Int = { while(true) {} }()
(source_file (top_level_code_decl (brace_stmt (pattern_binding_decl (pattern_typed type='Int' (pattern_named type='Int' 'myVariable') (type_ident
(component id='Int' bind=Swift.(file).Int))) (call_expr type='Int' location=sample.swift:1:23 range=[sample.swift:1:23 - line:3:3] nothrow arg_labels= (closure_expr type='() -> Int' location=sample.swift:1:23 range=[sample.swift:1:23 - line:3:1] discriminator=0 (parameter_list) (brace_stmt (while_stmt (call_expr implicit type='Int1' location=sample.swift:2:10 range=[sample.swift:2:10 - line:2:15] nothrow arg_labels= (dot_syntax_call_expr implicit type='() -> Int1' location=sample.swift:2:10 range=[sample.swift:2:10 - line:2:15] nothrow (declref_expr implicit type='(Bool) -> () -> Int1' location=sample.swift:2:11 range=[sample.swift: 2:11 - line:2:11] decl=Swift.(file).Bool._getBuiltinLogicValue() function_ref=double) (paren_expr type='(Bool)' location=sample.swift:2:11 range=[sample.swift:2:10 - line:2:15] (call_expr implicit type='Bool' location=sample.swift:2:11 range=[sample.swift:2:11 - line:2:11] nothrow arg_labels=_builtinBooleanLiteral: (constructor_ref_call_expr implicit type='(Int1) -> Bool' location=sample.swift:2:11 range=[sample.swift:2:11 - line:2:11] nothrow (declref_expr implicit type='(Bool.Type) -> (Int1) -> Bool' location=sample.swift:2:11 range=[sample.swift:2:11 - line:2:11] decl=Swift.(file).Bool.init(_builtinBooleanLiteral:) function_ref=single) (type_expr implicit type='Bool.Type' location=sample.swift:2:11 range=[sample.swift:2:11 - line:2:11] typerepr='Bool')) (tuple_expr implicit type='(_builtinBooleanLiteral: Builtin.Int1)' location=sample.swift:2:11 range=[sample.swift:2:11 - line:2:11] names=_builtinBooleanLiteral (boolean_literal_expr type='Builtin.Int1' location=sample.swift:2:11 range=[sample.swift:2:11 - line:2:11] value=true))))) (tuple_expr implicit type='()')) (brace_stmt)))) (tuple_expr type='()' location=sample.swift:3:2 range=[sample.swift:3:2 - line:3:3]))) )) (var_decl "myVariable" type='Int' interface type='Int' access=internal let storage_kind=stored))
(closure_expr type='() -> Int' location=sample.swift:1:23 range=[sample.swift:1:23 - line:3:1] discriminator=0 let
myVariable: Int = { while(true) {} }()
let _: Int = { preconditionFailure() }() let _: Void
= { fatalError() }() let _: Never = { while(true) {} }()
class SomeClass { lazy var v: Int = { preconditionFailure("Variable
'\(#function)' used before being initialized") }()
class SomeClass { var v: Int! lazy var v: Int
= { preconditionFailure("Variable '\(#function)' used before being initialized") }()
Closure
let _: (Int) -> Int = { $0 + 1
}
func f(x: Int...) -> String { … } let _:
(Int...) -> String = f
struct SomeType { func f(x: Int) -> String { …
} } let _: (Int) -> String = SomeType().f let _: (SomeType) -> (Int) -> String = SomeType.f
enum Rank: Int { case ace = 1 case two,
three, four, five, six, seven, eight, nine, ten case jack, queen, king } let _: (Int) -> Rank? = Rank.init init?(rawValue: Int)
let _: (Int, Int) -> (Int) = (+) let _:
(inout Int, Int) -> () = (+=)
enum Page { case settings case externalSite(URL) let _: (URL)
-> Page = Page.externalSite }
static var settings: Page { return Page.settings } static func
externalSite(_ url: URL) -> Page { return Page.externalSite(url) } let _: (URL) -> Page = Page.externalSite enum Page { case settings case externalSite(URL) }
[1.1, 3.2 ,3.5].map(round) [1.1, 3.2 ,3.5].sorted(by: <) ["www.ezura.me", ""].flatMap(URL.init)
inout
let _: (Int...) -> String = f let _: (Int)
-> String = SomeType().f let _: (SomeType) -> (Int) -> String = SomeType.f let _: (Int, Int) -> (Int) = (+) let _: (inout Int, Int) -> () = (+=) let _: (URL) -> Page = Page.externalSite inout
static func +=(lhs: inout Self, rhs: Self) var x =
1 // x: 1 x += 1 // x: 2 inout
! error: Escaping closures can only capture inout parameters explicitly
by value func f(_ arg: inout String) -> () -> () { return { print(arg) } }
func f(_ arg: inout String) { arg = "" arg
= "" } var testString = "" { didSet { print("changed: \(testString)") } } f(&testString) changed:
change to “" change to “" func f(_ arg: inout
String) var testString "" "" "" "" ""
current testString: changed: func f(_ arg: inout String) { arg
= "" sleep(2) arg = "" } var testString = "" { didSet { print("changed: \(testString)") } } DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(1)) { print("current testString: \(testString)") } f(&testString)
func f(_ arg: inout String) { arg = "" sleep(2)
arg = "" } var testString = "" /* { didSet { print("changed: \(testString)") } } */ DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(1)) { print("current testString: \(testString)") } f(&testString) current testString:
change to “" change to “" func f(_ arg: inout
String) var testString "" "" ""
func f(_ arg: inout String) inout change to “" change
to “" var testString "" "" "" "" "" ""
inout return defer
defer execute after all other code in the scope
x++, ++x or neither? /* ??? */ func ++(x: inout
Int) -> Int { defer { x += 1 } return x }
postfix func ++(x: inout Int) -> Int { defer {
x += 1 } return x } x++
func f() { let v: String defer { print(v) }
v = "init value" }
func f() { let v: String defer { print(v) }
v = "init value" }
class SomeType { var v: String { didSet { …
} } init() { defer { v = " in defer" } v = "" v = "" } }
deinit { defer { v = "goodbye in defer" }
changeV() _ = { v = "goodbye in block" }() }
Swift Tour = (obj?.myVariable = 50) .map { /* …
*/ } { while(true) {} }() let _: (inout Int, Int) -> () = (+=) let _: (URL) -> Enum = Enum.case Closure
inout func f(_ arg: inout String) -> () -> ()
{ return { print(arg) } } copy-in copy-out / Optimized inout defer return
defer init() { defer { v = " in defer"
} v = " initialize" } deinit { v = "goodbye " defer { v = "goodbye in defer" } }
Swift Tour myVariable = 50 obj?.myVariable = 50 return Closure
defer didSet inout enum Never init, deinit
Thank you for listening!!