テーマ 第一部: モダンなプログラミング言語としてのSwift Swiftの言語仕様やコンパイラなどについて語ります。 キーワード Swift 4.1 SwiftとObjective-C Swiftと他の言語 マルチプラットフォーム Conditional conformance Memory ownership 第二部: iOSアプリの開発言語としてのSwift iOSアプリを開発するにあたって、よりSwiftyな手法やAppleのフレームワークとの上手な付き合い方などについて語ります。 キーワード UIKitとIUO より安全にUIKitを扱う方法struct Box<T> { let value: T } extension Box: Equatable where T: Equatable { static func == (lhs: Box, rhs: Box) -> Bool { return lhs.value == rhs.value } }func ==<X>(a: [X], b: [X]) where X: Equatable { ... } (edited)//:configuration = Release OTHER_SWIFT_FLAGS = -enable-experimental-conditional-conformances //:completeSettings = some OTHER_SWIFT_FLAGSfunc == いらない?// Will not currently compile protocol Sequence { associatedtype SubSequence: Sequence where Iterator.Element == SubSequence.Iterator.Element, SubSequence.SubSequence == SubSequence // Returns a subsequence containing all but the first 'n' items // in the original sequence. func dropFirst(_ n: Int) -> Self.SubSequence // ... }// Test for a simulator destination #if (arch(i386) || arch(x86_64)) && (!os(macOS)) print("Simulator") #else print("Device") #endif // More restrictive test for iOS simulator // Adjust the os test for watchOS, tvOS #if (arch(i386) || arch(x86_64)) && os(iOS) // iOS simulator code #endifprotocol で init を書くと self を上書きできるcoder aDecoder: NSCoder を実装すればstatic func make() -> Self を実装すれば良いのではinit(withNibName: ) にnilをつっこむと、その<クラス名>.nibから生成できるprotocol Factoryable { init(factory: () -> Self) } extension Factoryable { init(factory: () -> Self) { self = factory() } } class MyAnimal: Factoryable { convenience init(name: String) { if name.contains("Cat") { self.init { MyCat() } } else { self.init { MyDog() } } } } class MyCat: MyAnimal { var meou: String { return "meou" } } class MyDog: MyAnimal { } let x = MyCat(name: "Dog") x.meou // Crash!!import Foundation protocol Factoryable { init(factory: () -> Self) } extension Factoryable { init(factory: () -> Self) { self = factory() } } class MyAnimal: Factoryable { convenience init(name: String) { if name.contains("Cat") { self.init { MyCat() } } else { self.init { MyDog() } } } } class MyCat: MyAnimal { var meou: String { return "meou" } } class MyDog: MyAnimal { func bark(arg: String) -> String { return arg } } let x = MyCat(name: "Dog") let y = x.meou // Crash!!rintaro - 2017/05/19 https://gist.github.com/rintaro/b16f05411cfe540754285dcc0da60174 Gist factory_init.swift これも Dog(type: "cat") 呼べちゃうっていう問題がきつい この辺で話題になった// RUN: %target-typecheck-verify-swift -swift-version 4dynamic_self_swift4 // Semi-bogus factory init pattern static func init の話もしてたけど、それは少なくともまだ戻り値の型がちゃんと正しい型でしたな、こいつ Dog なのにデバッグ情報としての型は Cat (edited)init(factory: () -> Self)のwitness-tableには、Cat,Dogはなくて、Animalだけがある、だから、convenience initはCat/Dogからは呼べない、が正しいと思うんですよねself = factory() が書けるのが問題な気が…通常のclassの convenience init でも self = ... はエラーになるはずprotocol SomeProtocol: nonclass くる?class Animal { factory init(name: String) { ... } } class Cat: Animal { init() { super.init(name: "Cat") } } // Compile Error Cat.init(name: "Cat") // Compile Errorinit(throws x: String) throws { // この中でOptionalなsuper.init(convenienceでself.init)を呼んでnilならErrorを出したい } これめちゃくちゃ困ってるんですが、classだけで完結できる方法ありますかね?struct Box<T> { let value: T } extension Box: Equatable where T: Equatable { static func == (lhs: Box, rhs: Box) -> Bool { return lhs.value == rhs.value } } これが普通に動いてる気がするdictionaryRepresentationしてからファイルにしたらいいんじゃないかな。protocol Foo { associatedtype Bar func foo<T: HasB>(t: T) where T.B == Bar } protocol HasB { associatedtype B } struct C<E>: Foo { typealias Bar = [E] } この状態でCにfooを補完させると func foo<T>(t: T) where T : HasB, [E] == T.B { } というコンパイルの通らないコードが補完されるCurPtr = BufferEnd 確かにこれいきなり出てきたらギョッとする{ ∃X where X: P, X } より { ∃X ∈ P, X } のほうがいいかもなって思ったbody が T を受けてくれたらいいのに・・・。self.disposeBag = nil // その他処理... } みたいなときに、 deinit の発行が その他処理の「後」になることがあり得るか?という話に関しては、無いかなーと思っていますが、検証はしていません。 (edited)protocol P {} protocol Foo { var foo: Int { get } } extension Int: P {} extension Array: Foo where Element: P { var foo: Int { return count } } let a = [1,2,3] print(a is Foo) (edited)main.swift:12:9: warning: 'is' test is always true print(a is Foo) ^ warning: Swift runtime does not yet support dynamically querying conditional conformance ('Swift.Array<Swift.Int>': 'main.Foo') Could not cast value of type 'Swift.Array<Swift.Int>' (0x7f6f03a20240) to 'main.Foo' (0x7f6f03a20280). #0 0x0000000003f24d64 PrintStackTraceSignalHandler(void*) (/usr/bin/swift+0x3f24d64) #1 0x0000000003f250a6 SignalHandler(int) (/usr/bin/swift+0x3f250a6) #2 0x00007f6f07f2c390 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x11390) #3 0x00007f6f0666b428 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x35428) #4 0x00007f6f0666d02a abort (/lib/x86_64-linux-gnu/libc.so.6+0x3702a) #5 0x00007f6f038fbf13 (/usr/lib/swift/linux/libswiftCore.so+0x39df13) #6 0x00007f6f038f84d9 (/usr/lib/swift/linux/libswiftCore.so+0x39a4d9) #7 0x00007f6f038f852b (/usr/lib/swift/linux/libswiftCore.so+0x39a52b) #8 0x00007f6f038f9a78 _dynamicCastToExistential(swift::OpaqueValue*, swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetExistentialTypeMetadata<swift::InProcess> const*, swift::DynamicCastFlags) (/usr/lib/swift/linux/libswiftCore.so+0x39ba78) #9 0x00007f6f0835b2ad #10 0x00007f6f0835b10e #11 0x0000000000fed1ce llvm::MCJIT::runFunction(llvm::Function*, llvm::ArrayRef<llvm::GenericValue>) (/usr/bin/swift+0xfed1ce) #12 0x0000000000ff1692 llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, char const* const*) (/usr/bin/swift+0xff1692) #13 0x00000000004d9076 swift::RunImmediately(swift::CompilerInstance&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, swift::IRGenOptions&, swift::SILOptions const& (edited)truestderr:main.swift:12:9: warning: 'is' test is always true print(a is Foo) ^protocol P {} protocol Foo { var foo: Int { get } } extension Int: P {} extension Array: Foo where Element: P { var foo: Int { return count } } let a = [1,2,3] print(a is Foo)protocol P {} protocol Foo { var foo: Int { get } } extension Int: P {} extension Array: Foo where Element: P { var foo: Int { return count } } let a = [1,2,3] print(a is Foo)swift-4.0-RELEASE/usercode/main.swift:7:1: error: extension of type 'Array' with constraints cannot have an inheritance clause extension Array: Foo where Element: P { ^ ~~~swift-4.0.2-RELEASE/usercode/main.swift:7:1: error: extension of type 'Array' with constraints cannot have an inheritance clause extension Array: Foo where Element: P { ^ ~~~swift-4.0.3-RELEASE/usercode/main.swift:7:1: error: extension of type 'Array' with constraints cannot have an inheritance clause extension Array: Foo where Element: P { ^ ~~~swift-4.1-RELEASE/usercode/main.swift:12:9: warning: 'is' test is always true print(a is Foo) ^ warning: Swift runtime does not yet support dynamically querying conditional conformance ('Swift.Array<Swift.Int>': 'main.Foo') Could not cast value of type 'Swift.Array<Swift.Int>' (0x7fc841935240) to 'main.Foo' (0x7fc841935280). /usr/bin/swift[0x3f24d54] /usr/bin/swift[0x3f25096] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11390)[0x7fc845641390] /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x38)[0x7fc843d80428] /lib/x86_64-linux-gnu/libc.so.6(abort+0x16a)[0x7fc843d8202a] /usr/lib/swift/linux/libswiftCore.so(+0x39df13)[0x7fc841810f13] /usr/lib/swift/linux/libswiftCore.so(+0x39a4d9)[0x7fc84180d4d9] /usr/lib/swift/linux/libswiftCore.so(+0x39a52b)[0x7fc84180d52b] /usr/lib/swift/linux/libswiftCore.so(+0x39ba78)[0x7fc84180ea78] [0x7fc845a702ad] [0x7fc845a7010e] /usr/bin/swift[0xfed1ce] /usr/bin/swift[0xff1692] /usr/bin/swift[0x4d9076] /usr/bin/swift[0x4c35d3] /usr/bin/swift[0x4beecc] /usr/bin/swift[0x4778c4] ...swift-4.1.1-RELEASE/usercode/main.swift:12:9: warning: 'is' test is always true print(a is Foo) ^ warning: Swift runtime does not yet support dynamically querying conditional conformance ('Swift.Array<Swift.Int>': 'main.Foo') Could not cast value of type 'Swift.Array<Swift.Int>' (0x7f2e73ecc240) to 'main.Foo' (0x7f2e73ecc280). /usr/bin/swift[0x3f24d64] /usr/bin/swift[0x3f250a6] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11390)[0x7f2e77bd8390] /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x38)[0x7f2e76317428] /lib/x86_64-linux-gnu/libc.so.6(abort+0x16a)[0x7f2e7631902a] /usr/lib/swift/linux/libswiftCore.so(+0x39df13)[0x7f2e73da7f13] /usr/lib/swift/linux/libswiftCore.so(+0x39a4d9)[0x7f2e73da44d9] /usr/lib/swift/linux/libswiftCore.so(+0x39a52b)[0x7f2e73da452b] /usr/lib/swift/linux/libswiftCore.so(+0x39ba78)[0x7f2e73da5a78] [0x7f2e780072ad] [0x7f2e7800710e] /usr/bin/swift[0xfed1ce] /usr/bin/swift[0xff1692] /usr/bin/swift[0x4d9076] /usr/bin/swift[0x4c35d3] /usr/bin/swift[0x4beecc] /usr/bin/swift[0x4778c4] ...swift-4.2-DEVELOPMENT-SNAPSHOT-2018-05-02-atrue/usercode/main.swift:12:9: warning: 'is' test is always true print(a is Foo) ^protocol P {} protocol Foo { var foo: Int { get } } extension Int: P {} extension Array: Foo where Element: P { var foo: Int { return count } } let a = [1,2,3] print(a is Foo)swift-4.2-DEVELOPMENT-SNAPSHOT-2018-05-02-atrue/usercode/main.swift:12:9: warning: 'is' test is always true print(a is Foo) ^where Key == Value やばそうprotocol A { static func foo() } extension Dictionary: A where Key == Value { static func foo() { print(type(of: self)) } } extension Array where Element: A { static func foo() { Element.foo() } } [String: String].foo() // Dictionary<String, String> [[String: String]].foo() // Dictionary<Dictionary<String, String>, Dictionary<String, String>>protocol A { static func foo() } extension Dictionary: A where Key == Value { static func foo() { print(type(of: self)) } } extension Array where Element: A { static func foo() { Element.foo() } } [String: String].foo() // Dictionary<String, String> [[String: String]].foo() // Dictionary<Dictionary<String, String>, Dictionary<String, String>>swift-4.2-DEVELOPMENT-SNAPSHOT-2018-05-02-aDictionary<String, String>.Type Dictionary<String, String>.Typeprotocol A {} protocol B: A {} protocol C: A {} protocol D: B, C {} struct X<T>: A{} extension X: D where T == Int { // Type 'X<T>' does not conform to protocol 'B' }main.swift:11:1: error: conditional conformance of type 'X<T>' to protocol 'D' does not imply conformance to inherited protocol 'B' extension X: D where T == Int { // Type 'X<T>' does not conform to protocol 'B' ^ main.swift:11:1: error: conditional conformance of type 'X<T>' to protocol 'D' does not imply conformance to inherited protocol 'C' extension X: D where T == Int { // Type 'X<T>' does not conform to protocol 'B' ^ main.swift:11:1: note: did you mean to explicitly state the conformance like 'extension X: C where ...'? extension X: D where T == Int { // Type 'X<T>' does not conform to protocol 'B' ^import PlaygroundSupport するのはPlaygroundBookでしかできない? Linked Frameworks からaddするのかと思ったらそれもできないし@objc protocol Foo { optional func aaa() }let a: [String] = [] let b: [Int] = a as! [Int] (edited)@escaping/@noescape はオーバーロードできる?func a(_ f: @escaping () -> ()) { } func a(_ f: () -> ()) { }func a(_ f: @escaping () -> ()) { } func a(_ f: () -> ()) { }swift-4.1.1-RELEASE/usercode/main.swift:2:6: error: invalid redeclaration of 'a' func a(_ f: () -> ()) { } ^ /usercode/main.swift:1:6: note: 'a' previously declared here func a(_ f: @escaping () -> ()) { } ^@objc をつけると作れるprotocol A {} class B: A{} class C: A{} vs enum A { case b(B) case c(C) }class A { func hoge(a: Sub) -> Sub { return Sub() } } class B: A { override func hoge(a: Super) -> SubSub { return SubSub() } } class Super {} class Sub: Super {} class SubSub: Sub {} (edited)class A { func hoge(a: Sub) -> Sub { return Sub() } } class B: A { override func hoge(a: Super) -> SubSub { return SubSub() } } class Super {} class Sub: Super {} class SubSub: Sub {}swift-4.1.1-RELEASEAny と String のときダメなんです??protocol Myself {} extension Myself { var `Self`: Self.Type { return type(of: self) } static var `Self`: Self.Type { return self } } class Foo: Myself { func bar() { Self.hoge() } static func baz() { Self.hoge() } static func hoge() { print("called") } } 今でもこういうことはできると聞きましたenum vs protocol をやっていきたいと思います。 protocol A {} class B: A{} class C: A{} vs enum A { case b(B) case c(C) }sealdがないので、protocolを利用した上の例では、予想しないような実装(クラス・構造体)が作られる恐れがあり、またパターンマッチで網羅性を検査することができません。enumがいいのか、という議論になるかというとそうではなくて、(勘違いだったら申し訳ないんですが)Swiftのenumの各タグ(?、たとえば上記の例でいうaとかb)はたしか型パラメーターが取れないです。protocolをつかって次のようにやるしかない、といった感じになるんじゃないでしょうか。 public protocol HList { } public struct HNil: HList { init() { } } public struct HCons<H, T: HList>: HList { public let head: H public let tail: T public init(_ h: H, _ t: T) { self.head = h self.tail = t } }HNilとHConsがありますが、HConsが型パラを取るので、こうしています。enumだと各タグ(?)は型パラメーターが取れないから、enumではできそうにない、という例として使いました。 (edited)enum HList0 { case `nil` } enum HList1<T1> { case `nil` case list0(HList0) } enum HList2<T1, T2> { case `nil` case list1(HList1<T2>) } enum HList3<T1, T2, T3> { case `nil` case list2(HList2<T3, T3>) }HCons と HNil の二つがあればいいんじゃない?public protocol HList { } public struct HNil: HList { init() { } } public struct HCons<H, T: HList>: HList { public let head: H public let tail: T public init(_ h: H, _ t: T) { self.head = h self.tail = t } }// Kotlin sealed class HList { class HNil: HList() class HCons<H, T: HList>(val head: H, val tail: T): HList() }head と tail にマッチングできないかな?
HCons<Int, HCons<String, HCons<Bool, HNil>>> とは、先頭の値の型が Int であり、かつ2番目の値の型が String であり、そして3番目の値の型が Bool であることを示している。switch list { case let .Cons(v): ??? case let .Nil: ??? } みたいな switch list { case let .Cons(v): ??? case let .Cons(.Cons(v)): ??? }protocol HListProtocol { associatedtype HeadType associatedtype ConsType: HListProtocol func asEnum() -> EHList<HeadType, ConsType> } indirect enum EHList<H, L: HListProtocol> { case `nil` case cons(H, EHList<L.HeadType, L.ConsType>) }switch hlist { // たとえばhlistの型は HCons<Int, HCons<String, HCons<Bool, HNil>>> だとする。これはコンパイラなら知ってるぞ case let .HCons(v): ??? // 当然 :point_up: の先頭の型は Int だから、vはIntだぞ case let .HNil: ??? }HListならまあ、どうにかJavaでもできそうなんですけど、HListの値があったとき、それらをアペンドする関数をかけるか?というのは実はSwiftとかじゃないとキビしいと思います。HCons<Int, HCons<String, HCons<Bool, HNil>>>とHCons<Int, HCons<String, HCons<Bool, HNil>>>があったら、アペンドするとHCons<Int, HCons<String, HCons<Bool, HCons<Int, HCons<String, HCons<Bool, HNil>>>>>>という型が帰ってくる関数です。extensionが型パラメーター取れないんだった!extension Optional { func flatten<T>() -> T? where Wrapped == T? { return flatMap { $0 } } }extension<T> Optional where Wrapped == T? { func flatten() -> T? { return flatMap { $0 } } }extensionで型パラ取らせてくれーassosicatedtypeしているので、関数の中というよりは、extensionの中ですぐ必要な感じです。public protocol HAppend { associatedtype A: HList associatedtype B: HList associatedtype C: HList static func append(_ hl1: A, _ hl2: B) -> C } extension<D: HList> HAppend { typealias A = HNil typealias B = D typealias C = D static func append(_ hl1: Nil, _ hl2: D) -> D = hl2 } (edited)Natを作って、それつかってHLIstにアクセスしているけど、同様にこういうのもつくれない……)interface Event { timestamp: number; } interface MouseEvent extends Event { x: number; y: number } function listenEvent(eventType: EventType, handler: (n: Event) => void) { /* ... */ } // Unsound, but useful and common listenEvent(EventType.Mouse, (e: MouseEvent) => console.log(e.x + "," + e.y));Qonceptのエンジニア。Swiftについて思ったことをつらつらとQiitaに書いてたら、なぜかtry! Swiftで発表することになった。最近は機械学習関係の業務も多く、Swiftで機械学習できないか模索中。@"$S4main3CatVAA6AnimalAAWP" = hidden constant [3 x i8*] [i8* bitcast (%swift.protocol_conformance_descriptor* @"$S4main3CatVAA6AnimalAAMc" to i8*), i8* bitcast (%swift.metadata_response (i64)* @"$SSiMa" to i8*), i8* bitcast (void (%TSi*, %T4main3CatV*, %swift.type*, i8**)* @"$S4main3CatVAA6AnimalA2aDP3foo5ValueQzyFTW" to i8*) ], align 8typedef について大阪 C++ 勉強会でちょっと話題が出ていて,そういえば typedef がどうしてダメで型エイリアスだと良いのかみたいな話あまりまとまってない気がしたのでメモ. typedef はこんな感...auto return types without trailing type information). Joe mentioned that there was some interest in switching the rest of swift to C++14 as well. I figured that I would just start a thread here t...enum class WriteImplKind { /// It's immutable. Immutable, /// There's storage. Stored, /// There are observers on top of the storage. /// TODO: maybe add a StoredWithDidSet here and to ReadWriteImplKind? StoredWithObservers, /// There are observers on top of the superclass's write implementation. InheritedWithObservers, /// There's a setter. Set, /// There's a mutable addressor. MutableAddress, /// There's a modify coroutine. Modify, };otoolコマンドでリンクしているlibswiftCore を調べられるrdar://problem/16997751 って見れないんでしたっけ func test1() throws { let parser = Parser(string: "$S13ExampleNumber6isEven6numberSbSi_tKF") let node = try parser.parse() XCTAssert(node.isEqualString( Node.symbol(start: .start(pos: 0, string: "$S"), entity: .entity(context: .module(Identifier(pos: 0, string: "ExampleNumber")), body: .function(name: Identifier(pos: 0, string: "isEven"), labelList: [ Identifier(pos: 0, string: "number") ])) ) ) ) }▿ SwiftDemangler.Node.symbol ▿ symbol: (2 elements) ▿ start: SwiftDemangler.Node.start ▿ start: (2 elements) - pos: 0 - string: "$S" ▿ entity: SwiftDemangler.Node.entity ▿ entity: (2 elements) ▿ context: SwiftDemangler.Node.module ▿ module: SwiftDemangler.Identifier - pos: 2 - string: "ExampleNumber" ▿ body: SwiftDemangler.Node.function ▿ function: (4 elements) ▿ name: SwiftDemangler.Identifier - pos: 17 - string: "isEven" ▿ labelList: 1 element ▿ SwiftDemangler.Identifier - pos: 24 - string: "number" ▿ retType: SwiftDemangler.Type.single ▿ single: (1 element) - name: "Swift.Bool" ▿ argType: SwiftDemangler.Type.list ▿ list: 1 element ▿ SwiftDemangler.Type.single ▿ single: (1 element) - name: "Swift.Int"for character in source { switch character { case "{": tokens.append(.leftBrace(...)) case "(": tokens.append(.leftParen(...)) case "'": tokens.append(.singleQuote(...)) ... case " ". "\t", "\n": tokens.append(.whitespace(...)) ... default: tokens.append(.character(...)) } } ^ みたいにして先読みもバックトラックもせずに一気にループで一回 String を [Token] にして、その後 [Token] をもう一度頭からループして今度は先読みしたり戻ったりをしながら意味のある構造に区切っていくのがシンプルじゃないかな。 [Token] だったら String を行ったり来たりするよりもよほど簡単。[Token] を作る処理で、どうせもう一度読むので [Character] より多少マシ、くらい。そういう意味だと [Character] でもいいけどどうせ一回 String を全部読むなら多少は情報を追加しといたほうがいいかな、という感じですね。classとか funcの予約語やIdentifierに分けるのは簡単だし、Stringの端から端まで読み飛ばすのも楽だし、というのが楽になるくらい。enum Token { case whitespace(raw: String, line: Int, column: Int) ... } のようにするかも?enum E { case c(Bool) } let e = E.c(true) switch e { case .c(let b) where b == true: print(1) case .c(let b) where b == false: print(2) case .c(true): print(3) case .c(false): print(4) }print(type(of: AnyCollection<String>(["hello"]).startIndex)) print(type(of: AnyCollection<Character>("hello").startIndex)) print(type(of: ["hello"].startIndex)) print(type(of: "hello".startIndex))AnyIndex AnyIndex Int Indexvar _p: XXX! // ① struct S { var p: some P { get { ... } set { ... } } } _p = S().p S().p = _p as! XXX // ② こういうことやりたい場合、①か②で「S.pのORT型」を明示的に表現しなきゃいけないけど、どうやって書けばいいんだろう (edited)struct S { func a() -> some P func b() -> some P } 今言ったの、このふたつが共存できないって話??func f() -> some P1 func f() -> some P2 が駄目ということlet p: P1 = f()struct S { func f() -> some P } let ss: [S] = ... let arr: [XXX] if cond { arr = ss.map { $0.f() } } else { arr = ... } (edited)func g<X: P1>(_ x: X) { } g(f())./docs/TypeChecker.rst:126: called. Conversion constraints are written ``X <c Y``, read as ./docs/TypeChecker.rst:261: conversion constraint ``T(b) <c T0`` captures the requirement that ./docs/TypeChecker.rst:284: respectively. The constraint ``T(b) <c T0`` requires the key ./docs/TypeChecker.rst:324: constraints ``T(y) <c T0`` and ``T(z) <c T0`` capture the need for ./docs/TypeChecker.rst:503: A -> B <c C -> D ./docs/TypeChecker.rst:594:placed on it that relate it to concrete types, e.g., ``T0 <c Int`` or ./docs/TypeChecker.rst:595:``Float <c T0``. In these cases, we can use the concrete types as a ./docs/TypeChecker.rst:741:these constraints is broken down into "``T2 <c Int``" and "``X <c ./docs/TypeChecker.rst:763:applied. Similarly, the "``(T2, X) <c T0`` constraint has a ./docs/TypeChecker.rst:772:example, the ``T2 <c Int`` constraint will be anchored at the function ./docs/TypeChecker.rst:776:element. Similarly, the ``X <c String`` constraint will have the same ./docs/TypeChecker.rst:789:simplifying the constraint ``X <c String``, so it uses the locator ./docs/TypeChecker.rst:842:Here, the failing constraint is ``Float <c Int``, with the same ./lib/Sema/CSSimplify.cpp:6596: // T <c U ===> T? <c U! ./lib/Sema/CSSimplify.cpp:6715: // T < U or T is bridged to V where V < U ===> Array<T> <c Array<U> ./lib/Sema/CSSimplify.cpp:6730: // Dictionary<K1, V1> <c Dictionary<K2, V2> ./lib/Sema/CSSimplify.cpp:6764: // T1 < T2 || T1 bridges to T2 ===> Set<T1> <c Set<T2> ./lib/Sema/CSSimplify.cpp:6778: // T1 <c T2 && T2 : Hashable ===> T1 <c AnyHashable ./lib/Sema/CSSimplify.cpp:6809: // T' < U and T a toll-free-bridged to T' ===> T' <c U ./lib/Sema/CSSimplify.cpp:6824: // T < U' and U a toll-free-bridged to U' ===> T <c U <C where C : ...> みたいなのが引っかかりまくる ./test/SIL/Parser/witness_with_inherited_gp.sil:59:// IndexingIterator<_mmArrayBuffer<T>>: specialize <C = _mmArrayBuffer<T>, ./docs/Generics.rst:574:and the constraints expressed in the angle brackets (e.g., <C : ./docs/TypeChecker.rst:130: A construction constraint, written ``X <C Y`` requires that the ./docs/TypeChecker.rst:268: a construction constraint ``T(b) <C A``, which requires that ``A`` rstが古くて消えてないだけってのは正しそうThis copy of libswiftCore.dylib requires an OS version prior to 10.14.4. Abort trap: 6 の対策って文脈で合ってます? (edited).id で比較してました。{ (x) -> Int in 4 }(3)valueToOptional なんだから OptionalType だろうと思って、乱暴に as! でキャストしてるInjectIntoOptionalExpr and coerceInt? だとしたら、3 を Int にcoerceして、それを Int? に包む感じなのかな。let expr = してる。let expr = したんだろうな。if let resultTy = node.returnType { if let lastBody = node.body.popLast() as? Expr { let expr = try solution.coerce(expr: lastBody, to: resultTy) node.body.append(expr) } }as? が成り立たなかったら、bodyの最後が消えてるな。。。node.body = try [solution.coerce(expr: node.body.last as! Expr, to: (node.type as! FunctionType).result)]if let retTy = node.returnType, let last = node.body.removeLast() as? Expr { node.body.append(try solution.coerce(expr: last, to: retTy)) }returnType を使ってる。同じ間違いしてる。f([Cat()]) ^ あとでこのArrayリテラルをSetでうけるやつを試すclass Cat {} func f(_ a: AnyObject) { } f(Cat.self)<stdin>:5:3: error: argument type 'Cat.Type' does not conform to expected type 'AnyObject' f(Cat.self) ^// 0 0 0 0 0 0 1 0 0 0 0 0: SK_NonDefaultLiteralが1 func f(a: Set<Int>) { print("a") } // func f(a: [Int]) { print("b") } f(a: [0]) // b (edited)// 0 0 0 0 0 0 1 0 0 0 0 0: SK_NonDefaultLiteralが1 func f(a: Set<Int>) { print("a") } // そもそも出ない @available(*, unavailable) func f(a: [Int]) { print("b") } f(a: [0]) // a (edited)わいわいswiftc #17 で森タワー(ヒルズ)に入るパスワードみたいなのってもう配信されてましたっけ?func outer<A>() { func inner() { } // A is artchetype inner() }any Pany P と <T: P> Tstruct A<T> { var value: T } print(MemoryLayout<Int>.size) print(MemoryLayout<String>.size) print(MemoryLayout<A<Int>>.size) print(MemoryLayout<A<String>>.size) (edited)A<Int> = { var value: Int } A<String> = { var value: String }Var はVarってクラスだからこうなるんだけど、パッと見大文字始まりだと違和感あるな例えば、 λx. x と λy. y は同じ関数を表している。((λx.M) E) → (M[x := E]) β-reduction Replacing the bound variables with the argument expression in the body of the abstraction.protocol HTraverse { associatedtype Source: HList func traverse(_ f: () -> Void) -> HNil } extension HCons: HTraverse where T: HTraverse { typealias Source = HCons<H, T> // おい!ここを@inlinableにさせてくれ!! func traverse(_ f: () -> Void) -> HNil { f() return self.tail.traverse(f) } } extension HNil: HTraverse { typealias Source = HNil public func traverse(_ f: () -> Void) -> HNil { f() return HNil() } }
HListをHNil まで型レベルで再帰していくことによって、たとえば HCons<String, HCons<Bool, HCons<Bool, HCons<Int, HCons<Optional<Int>, HCons<String, HCons<Bool, HCons<Bool, HCons<Int, HCons<Optional<Int>, HNil>>>>>>>>>> このように10回HCons がネストした型だと10回の違った(1つずつ展開された)呼び出され型がするため、その分の特殊化(?)でバイナリサイズが爆弾になることを期待してたんですが、コメントにあるとおり、狙った場所に @inlineable を書くとコンパイルがとおらない…… mayHaveSideEffects関数の実装の話かmapのoptimizationのはなしします_addr suffixに何の情報もなくて辛い命名だn 以外今の所無さそう //===----------------------------------------------------------------------===// // // This file defines the database of builtin functions. // // BUILTIN(Id, Name, Attrs) // - Id is an identifier suitable for use in C++ // - Name is a string literal for the name to which the builtin should be // bound in Swift // - Attrs specifies information about attributes of the function: // n -> readnone // //===----------------------------------------------------------------------===//c++ class FullApplySite : public ApplySite { explicit FullApplySite(void *p) : ApplySite(p) {} public: FullApplySite() : ApplySite() {} explicit FullApplySite(SILInstruction *inst) : ApplySite(inst) { assert(classof(inst) && "not an apply instruction?"); } FullApplySite(ApplyInst *inst) : ApplySite(inst) {} FullApplySite(BeginApplyInst *inst) : ApplySite(inst) {} FullApplySite(TryApplyInst *inst) : ApplySite(inst) {} static FullApplySite isa(SILNode *node) { auto *i = dyn_cast<SILInstruction>(node); if (!i) return FullApplySite(); auto kind = FullApplySiteKind::fromNodeKind(i->getKind()); if (!kind) return FullApplySite(); switch (kind.getValue()) { case FullApplySiteKind::ApplyInst: return FullApplySite(cast<ApplyInst>(node)); case FullApplySiteKind::BeginApplyInst: return FullApplySite(cast<BeginApplyInst>(node)); case FullApplySiteKind::TryApplyInst: return FullApplySite(cast<TryApplyInst>(node)); } llvm_unreachable("covered switch"); }NON_VALUE_INST(StoreInst, store, SILInstruction, MayWrite, DoesNotRelease) NON_VALUE_INST(AssignInst, assign, SILInstruction, MayWrite, DoesNotRelease)@xedin (edited)func f(aa: Int, bb: Int) {} func f(cc: Int, dd: Int) {} func main() { f(aa: 1, 2) }
7<stdin>:5:5: error: argument labels '(aa:, _:)' do not match any available overloads f(aa: 1, 2) ^~~~~~~~~~~ <stdin>:5:5: note: overloads for 'f' exist with these partially matching parameter lists: (aa: Int, bb: Int), (cc: Int, dd: Int) f(aa: 1, 2) ^<stdin>:5:6: error: missing argument label 'bb:' in call f(aa: 1, 2) ^ bb:
2f { } {} {} {} (ry うごくの?func f(_ a: (Void) -> Void...) { } f {} {} {} {} {} {}<stdin>:3:5: error: consecutive statements on a line must be separated by ';' f {} {} {} {} {} {} ^ ; <stdin>:3:6: error: top-level statement cannot begin with a closure expression f {} {} {} {} {} {} ^ <stdin>:3:11: error: consecutive statements on a line must be separated by ';' f {} {} {} {} {} {} ^ ; <stdin>:3:12: error: top-level statement cannot begin with a closure expression f {} {} {} {} {} {} ^ <stdin>:3:17: error: consecutive statements on a line must be separated by ';' f {} {} {} {} {} {} ^ ; <stdin>:3:18: error: top-level statement cannot begin with a closure expression f {} {} {} {} {} {} ^ <stdin>:1:13: warning: when calling this function in Swift 4 or later, you must pass a '()' tuple; did you mean for the input type to be '()'? func f(_ a: (Void) -> Void...) { } ^~~~~~ () <stdin>:3:9: error: argument passed to call that takes no arguments f {} {} {} {} {} {} ^~ <stdin>:3:15: error: argument passed to call that takes no arguments f {} {} {} {} {} {} ^~ <stdin>:3:18: error: closure expression is unused f {} {} {} {} {} {} ^ <stdin>:3:18: note: did you mean to use a 'do' statement? f {} {} {} {} {} {} ^ do Usage: @swiftNightly [SWIFT_OPTIONS] ``` [Swift Code] ```func f( a: (Void) -> Void...) { } f {} : {}<stdin>:3:5: error: consecutive statements on a line must be separated by ';' f {} : {} ^ ; <stdin>:3:6: error: expected expression f {} : {} ^ <stdin>:3:8: error: top-level statement cannot begin with a closure expression f {} : {} ^ <stdin>:1:12: warning: when calling this function in Swift 4 or later, you must pass a '()' tuple; did you mean for the input type to be '()'? func f( a: (Void) -> Void...) { } ^~~~~~ () <stdin>:3:8: error: closure expression is unused f {} : {} ^ <stdin>:3:8: note: did you mean to use a 'do' statement? f {} : {} ^ do func f( a: (Void) -> Void...) { } f {} _: {}<stdin>:1:12: warning: when calling this function in Swift 4 or later, you must pass a '()' tuple; did you mean for the input type to be '()'? func f( a: (Void) -> Void...) { } ^~~~~~ () <stdin>:2:3: error: extra arguments at positions #2, #2 in call f {} _: {} ^ <stdin>:1:6: note: 'f(a:)' declared here func f( a: (Void) -> Void...) { } ^func f(xx aa: String, xx bb: Int) {} f(xx: 1)<stdin>:2:3: error: missing argument for parameter 'xx' in call f(xx: 1) ^ xx: <#String#>, <stdin>:1:6: note: 'f(xx:xx:)' declared here func f(xx aa: String, xx bb: Int) {} ^func f(_ aa: String, _ bb: Int, cc: Int = 0) {} f(1)<stdin>:2:4: error: missing argument for parameter #2 in call f(1) ^ , <#Int#> <stdin>:1:6: note: 'f(_:_:cc:)' declared here func f(_ aa: String, _ bb: Int, cc: Int = 0) {} ^ <stdin>:2:3: error: cannot convert value of type 'Int' to expected argument type 'String' f(1) ^func f(aa: String = "", bb: Int) {} f(aa: 1)<stdin>:2:3: error: missing argument for parameter 'aa' in call f(aa: 1) ^ aa: <#String#>, <stdin>:1:6: note: 'f(aa:bb:)' declared here func f(aa: String = "", bb: Int) {} ^<stdin>:2:8: error: missing argument for parameter 'bb' in call f(aa: 1) ^ , bb: <#Int#> <stdin>:1:6: note: 'f(aa:bb:)' declared here func f(aa: String = "", bb: Int) {} ^<stdin>:2:3: error: missing argument for parameter 'aa' in call f(aa: 1) ^ aa: <#String#>, <stdin>:1:6: note: 'f(aa:bb:)' declared here func f(aa: String = "", bb: Int) {} ^func f(a: Int, b: Int, c: Int, d: Int) {} func f(a: Int, b: String, x: String, y: String) {} f(a: 0, b: 0, x: 0, y: 0)<stdin>:4:12: error: cannot convert value of type 'Int' to expected argument type 'String' f(a: 0, b: 0, x: 0, y: 0) ^ <stdin>:4:18: error: cannot convert value of type 'Int' to expected argument type 'String' f(a: 0, b: 0, x: 0, y: 0) ^ <stdin>:4:24: error: cannot convert value of type 'Int' to expected argument type 'String' f(a: 0, b: 0, x: 0, y: 0) ^func f(a: Int, b: Int, c: Int, d: Int) {} func f(a: Int, b: String, x: String, y: String) {} f(a: 0, b: 0, x: 0, y: 0) (edited)---Constraint solving for the expression at [<stdin>:4:1 - line:4:25]--- (disabled disjunction term $T0 bound to decl main.(file).f(a:b:c:d:)@<stdin>:1:6 : (Int, Int, Int, Int) -> () at <stdin>:1:6 [[locator@0x849fea0 [OverloadedDeclRef@<stdin>:4:1]]];) (introducing single enabled disjunction term $T0 bound to decl main.(file).f(a:b:x:y:)@<stdin>:2:6 : (Int, String, String, String) -> () at <stdin>:2:6 [[locator@0x849fea0 [OverloadedDeclRef@<stdin>:4:1]]];) (overload set choice binding $T0 := (Int, String, String, String) -> ()) (common result type for $T0 is ()) ---Initial constraints for the given expression--- (call_expr type='()' location=<stdin>:4:1 range=[<stdin>:4:1 - line:4:25] arg_labels=a:b:x:y: (overloaded_decl_ref_expr type='$T0' location=<stdin>:4:1 range=[<stdin>:4:1 - line:4:1] name=f number_of_decls=2 function_ref=single decls=[ main.(file).f(a:b:c:d:)@<stdin>:1:6, main.(file).f(a:b:x:y:)@<stdin>:2:6]) (tuple_expr type='(a: $T1, b: $T2, x: $T3, y: $T4)' location=<stdin>:4:2 range=[<stdin>:4:2 - line:4:25] names=a,b,x,y (integer_literal_expr type='$T1' location=<stdin>:4:6 range=[<stdin>:4:6 - line:4:6] value=0 builtin_initializer=**NULL** initializer=**NULL**) (integer_literal_expr type='$T2' location=<stdin>:4:12 range=[<stdin>:4:12 - line:4:12] value=0 builtin_initializer=**NULL** initializer=**NULL**) (integer_literal_expr type='$T3' location=<stdin>:4:18 range=[<stdin>:4:18 - line:4:18] value=0 builtin_initializer=**NULL** initializer=**NULL**) (integer_literal_expr type='$T4' location=<stdin>:4:24 range=[<stdin>:4:24 - line:4:24] value=0 builtin_initializer=**NULL** initializer=**NULL**))) Score: 0 0 0 0 0 0 0 0 0 0 0 0 Type Variables: $T0 [lvalue allowed] [noescape allowed] as (Int, String, String, String) -> () @ locator@0x849fea0 [OverloadedDeclRef@<stdin>:4:1] $T1 [noescape allowed] literal=3 bindings={(subtypes of) (default from ExpressibleByIntegerLiteral) Int} @ locator@0 (edited)func f(a: Int, b: String, x: String, y: String) {} func f(a: Int, b: Int, c: Int, d: Int) {} f(a: 0, b: 0, x: 0, y: 0)---Constraint solving for the expression at [<stdin>:4:1 - line:4:25]--- (disabled disjunction term $T0 bound to decl main.(file).f(a:b:c:d:)@<stdin>:2:6 : (Int, Int, Int, Int) -> () at <stdin>:2:6 [[locator@0x9279ea0 [OverloadedDeclRef@<stdin>:4:1]]];) (introducing single enabled disjunction term $T0 bound to decl main.(file).f(a:b:x:y:)@<stdin>:1:6 : (Int, String, String, String) -> () at <stdin>:1:6 [[locator@0x9279ea0 [OverloadedDeclRef@<stdin>:4:1]]];) (overload set choice binding $T0 := (Int, String, String, String) -> ()) (common result type for $T0 is ()) ---Initial constraints for the given expression--- (call_expr type='()' location=<stdin>:4:1 range=[<stdin>:4:1 - line:4:25] arg_labels=a:b:x:y: (overloaded_decl_ref_expr type='$T0' location=<stdin>:4:1 range=[<stdin>:4:1 - line:4:1] name=f number_of_decls=2 function_ref=single decls=[ main.(file).f(a:b:x:y:)@<stdin>:1:6, main.(file).f(a:b:c:d:)@<stdin>:2:6]) (tuple_expr type='(a: $T1, b: $T2, x: $T3, y: $T4)' location=<stdin>:4:2 range=[<stdin>:4:2 - line:4:25] names=a,b,x,y (integer_literal_expr type='$T1' location=<stdin>:4:6 range=[<stdin>:4:6 - line:4:6] value=0 builtin_initializer=**NULL** initializer=**NULL**) (integer_literal_expr type='$T2' location=<stdin>:4:12 range=[<stdin>:4:12 - line:4:12] value=0 builtin_initializer=**NULL** initializer=**NULL**) (integer_literal_expr type='$T3' location=<stdin>:4:18 range=[<stdin>:4:18 - line:4:18] value=0 builtin_initializer=**NULL** initializer=**NULL**) (integer_literal_expr type='$T4' location=<stdin>:4:24 range=[<stdin>:4:24 - line:4:24] value=0 builtin_initializer=**NULL** initializer=**NULL**))) Score: 0 0 0 0 0 0 0 0 0 0 0 0 Type Variables: $T0 [lvalue allowed] [noescape allowed] as (Int, String, String, String) -> () @ locator@0x9279ea0 [OverloadedDeclRef@<stdin>:4:1] $T1 [noescape allowed] literal=3 bindings={(subtypes of) (default from ExpressibleByIntegerLiteral) Int} @ locator@0commit 98522b0b7100a5e3657fd340214429c198039f0a (HEAD -> master, origin/master, origin/HEAD) Merge: b148e241867 439c1481bea Author: Hamish Knight <hamish_knight@apple.com> Date: Thu May 28 18:41:25 2020 -0700 Merge pull request #32067 from hamishknight/a-delayed-filingfunc foo<X>(_ aa: X, _ bb: Int) -> X { aa } foo((1, 2)) [1] これは第二引数が不足している [2] これは丸括弧が余計(tuple splat fixすべき) (edited)func foo<X, Y>(_ aa: X, _ bb: Y) -> X { aa } foo((1, 2)) [1] これは第二引数が不足している [2] これは丸括弧が余計(tuple splat fixすべき) (edited)func foo<X>(_ aa: X, _ bb: Int, _ cc: Int) -> X { aa } foo((1, 2, 3))error: failed to launch REPL process: process exited with status -1 (attach failed (Not allowed to attach to process. Look in the console messages (Console.app), near the debugserver entries when the attached failed. The subsystem that denied the attach permission will likely have logged an informative message about why it was denied.))template <class T> T add(T a, T b) { return a + b; } public func testAdd(x: Int32) -> Int32 { return add(x, x) } template <class T> T passThrough(T value) { return value; } public func testPassThroughAny(x: Any) -> Any { return passThrough(x) }An asynchronous handler behaves externally like a synchronous function, but internally it is handled like an asynchronous function, meaning that it can execute operations with suspension points such as calling other async functions. The body of the function is executed just as if it and its caller were async functions, except that the caller is resumed when the callee reaches its first suspension point rather than only when the callee exits.c++ if (argIdx == 0) { for (auto word : camel_case::getWords(selectorPiece)) { if (word == "did" || word == "Did") return true; } continue; }c++ static bool isCompletionHandlerParamName(StringRef paramName) { return paramName == "completionHandler" || paramName == "completion" || paramName == "withCompletionHandler"; } parser.add_argument('--enable-experimental-concurrency', action='store_true', help='Enable experimental concurrency model.')func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTaskURLSession.shared.dataTask(with: url) { (result: Result<(response: URLResponse, data: Data), Error>)extension URLSession { public func dataTaskPublisher(for url: URL) -> URLSession.DataTaskPublisher public func dataTaskPublisher(for request: URLRequest) -> URLSession.DataTaskPublisher public struct DataTaskPublisher : Publisher { public typealias Output = (data: Data, response: URLResponse) public typealias Failure = URLError } }Future 使って並列化するコードはこんな感じになるかと。 let a = Future { await foo() } let b = Future { await bar() } let sum = await a.get() + b.get()get で値を取り出せるのが違うところでしょうか。actor もマージされてるの、プロポーザル出る前からめちゃくちゃ動いてますね・・・。actor の使い方の参考になりそう。 https://github.com/DougGregor/swift/blob/099de9d3e589bc120717466a52cc42e483c016c0/test/Concurrency/actor_isolation.swift // Accesses on other actors can only reference immutable data or // call asychronous methods _ = otherActor.immutable // okay _ = otherActor.synchronous() // expected-error{{actor-isolated instance method 'synchronous()' can only be referenced on 'self'}} _ = await otherActor.asynchronous() _ = otherActor.text[0] // expected-error{{actor-isolated property 'text' can only be referenced on 'self'}}async/await は actor 関係ないかと。async/awaitasync/await は前座的な感じ。async/await は↓に切り出されてる。 https://gist.github.com/lattner/429b9070918248274f25b714dcfc7619beginAsync の body って @escaping じゃなくていいんですっけ? func beginAsync(_ body: () async throws -> Void) rethrows -> Void
https://gist.github.com/lattner/429b9070918248274f25b714dcfc7619 (edited)@escaping は非 async なクロージャにしかついてないし、そういう構文っぽい。beginAsync の throws と rethrows 要らないってずっと言ってたけど、 @asyncHandler では throws 禁止されてていい感じ。@asyncHandler が挿入されないのは inout 相当だから? - (void)refrigerator:(id)fridge didGetFilledWithIntegers:(NSInteger *)items count:(NSInteger)count;async/await と actor 周りの話をまとめました。 https://zenn.dev/koher/articles/swift6-concurrency
2suspendAsync 相当のものがないと作れないと思います。suspendAsync が Promise を作るのに相当するので。beginAsync については @asyncHandler になるようですが、 suspendAsync がどうなるかはこの前調べた時点ではまだ不明だったと思います。async/await を試せるようにオプションをつけて実行するようにしました。 https://swiftfiddle.com/ibz6zkexrbcmdd3zs2xz3oamkm ホントはネットワークリクエストとかそれっぽいサンプルを書きたかったけど書けないのでしょうがない。import Dispatch func suspendAsync<T>( _ body: (_ continuation: @escaping (T) -> ()) -> () ) async -> T { let semaphore = DispatchSemaphore(value: 0) var result: T! body { value in result = value semaphore.signal() } semaphore.wait() return result } extension DispatchQueue { func asyncAfter(deadline: DispatchTime) async { await suspendAsync { continuation in asyncAfter(deadline: deadline) { continuation(()) } } } } @asyncHandler func main() { print("A") await DispatchQueue.global().asyncAfter(deadline: .now() + 1) print("B") await DispatchQueue.global().asyncAfter(deadline: .now() + 1) print("C") } main()suspendAsync を作ってみました。async/await を使ったコードを書いてみるくらいの役にしか立ちません。Future で包むというのがプロポーザルに書かれてたと思います。let a = Future { await foo() } let b = Future { await bar() } let sum = await a.get() + b.get()@asyncHandler になるかと。await 忘れないのいいですよね。@IBAction @asyncHandler func onButtonPressed(_ sender: UIButton) { await sendValue(value, to: url) }beginAsync だったので、 @IBAction func onButtonPressed(_ sender: UIButton) { beginAsync { await sendValue(value, to: url) } } になるはずだったかと思います。async 忘れで待たずに抜けちゃいますし、 Kotlin の suspend は Swift の async と同じなんですが、 await 相当のものがないのでどこで await してるかぱっと見でわかんないんですよね。@asyncHandler は caller 側は待たずに抜けるんじゃないでしょうか。@IBAction はメインスレッドをブロックしたくないので caller 側を待たせたくないので。suspendAsync がなんちゃってで同期だからじゃないでしょうか?() の conformance が入った件let input = "1000000000000" let inputs = input.split(separator: "\n").map { Int($0)! } for i in inputs { var answers: Set<Int> = [] for n in 1...(Int(ceil(sqrt(Double(i))))) { if i % n == 0 { answers.insert(n) } } let i2 = i let b = answers for n in b { if i2 % n == 0 { answers.insert(i2 / n) } } let sorted = answers.sorted() for n in sorted { print(n) } }let input = readLine()! //let input = "720" let inputs = input.split(separator: "\n") for input in inputs { var answers: Set<Int> = [] let i = Int(input)! for n in 1...(Int(ceil(sqrt(Double(i))))) { if i % n == 0 { answers.insert(n) answers.insert(i / n) } } let sorted = answers.sorted() for n in sorted { print(n) } } (edited)quotientAndRemainder 無駄がない.map { [$0, n/$0] }.flatMap { $0 } (edited)trueを返す -@inlinable あるなしで実行時間にどのくらい影響あるものなんですかね? (edited)print((a: 1, b: 2) == (b: 1, a: 2)) // true (edited)-driver-print-graphvizif buildParameters.useExplicitModuleBuild {struct MyError1: Error {} struct MyError2: Error {} func throwError() throws { throw MyError1() } do { try throwError() } catch let error { switch error { case is MyError1: print("MyError1") case is MyError2: print("MyError2") default: print("other type") } } (edited)pure)、みたいなことは言えるというようなアプローチで同期もasync letできてしまうほうが自然か(?) (edited)async let dinner = { cookDinner() }
https://github.com/ktoso/swift-evolution/blob/wip-tasklocals/proposals/nnnn-task-locals.md#binding-values-for-the-duration-of-a-child-task (edited) // Wait for all of the chopping to complete, collecting the veggies into // the result array in whatever order they're ready. while let choppedVeggie = try await group.next() { choppedVeggies.append(choppedVeggie) }
https://github.com/apple/swift-evolution/blob/main/proposals/0304-structured-concurrency.md#task-groups-and-child-tasks (edited)struct S { func f( _ f1: () throws -> (), _ f2: () throws -> () ) rethrows -> () { } } S().f({ }, { })func a() -> some View ってやるときに @VIewBuilder つける (edited)func f(_: Never) -> Int {}func f(a: Never) -> Int {} (edited)struct Container<T> { func map<T, U>(_ transformer: (T) -> U) -> Container<U> { return .init() } } let n = Container<Never>() let u: Container<Int> = n.map { _ in } (edited)<stdin>:6:25: error: cannot find 'c' in scope let u: Container<Int> = c.map { _ in } ^<stdin>:6:31: error: cannot convert value of type '()' to closure result type 'Int' let u: Container<Int> = n.map { _ in } ^~~~~~~~ <stdin>:6:33: error: unable to infer type of a closure parameter '_' in the current context let u: Container<Int> = n.map { _ in } ^enum Command: Codable { case load(String) case store(key: String, Int) } would encoded to { "load": { "_0": "MyKey" } } and { "store": { "key": "MyKey", "_1": 42 } }Either< Int, Either< String, Int > > (edited)let dictionary: [String: Int] = .init { [ "a": 2, "b": 3, ] if isFoo { ["c": 5] } }enum Command: Codable { case load(key: String) case store(key: String, value: Int) } would be encoded to { "load": { "key": "MyKey" } } and { "store": { "key": "MyKey", "value": 42 } }type member must not be named 'Type', since it would conflict with the 'foo.Type' expression 専用のエラーメッセージあるわ
1Double.description の実装がめっちゃ凝ってたDouble.description は丸めた文字列作ってるんだろう?という話から。 $ swift Welcome to Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28). Type :help for assistance. 1> 0.1 $R0: Double = 0.10000000000000001 2> print(0.1) 0.1 3> print(0.1 + 0.2) 0.30000000000000004Float80サポートと共にFloatingPointの文字列化をSwiftDtoaに置き換えようとしてやめたことを思い出した。 https://github.com/jpsim/Yams/pull/151description implementation This replaces the current implementation of description anddebugDescription for the standard floating-point types with a new form...
* Always Accurate. Converting the decimal form back to binary (using an accurate algorithm such as Clinger's) will always yield exactly the original binary value. For the IEEE 754 formats, the round-trip will produce exactly the same bit pattern in memory. This is an essential requirement for JSON serialization, debugging, and logging.0.1 に丸められても 0.1 というリテラルから元の値が復元されるなら問題ないのかな?Float80のテストを通そうとすると、標準の手段だとダメだったからSwiftDtoaを使おうとしたと記憶。Float80のテストを通そうとすると、標準の手段だとダメだったからSwiftDtoaを使おうとしたと記憶。 $ swift Welcome to Apple Swift version 5.4.2 (swiftlang-1205.0.28.2 clang-1205.0.19.57). Type :help for assistance. 1> 0.1 $R0: Double = 0.10000000000000001 2> print(0.1) 0.1 3> 0.10000000000000001 $R1: Double = 0.10000000000000001 4> print(0.10000000000000001) 0.10.10000000000000001 を2進表現した時の値は 十進でいえば 0.10000000000000001 のほうが 0.1 より近いんじゃあないんか。 (edited)
1#define COMPATIBILITY_OVERRIDE_SECTION_NAME_swiftRuntime "__swift54_hooks" #define COMPATIBILITY_OVERRIDE_SECTION_NAME_swift_Concurrency "__s_async_hook"$ git diff swift-5.3-RELEASE swift-5.4-RELEASE -- include/swift/Runtime/RuntimeFunctions.def[omochi@omochi-iMacPro swift (main=)]$ git diff swift-5.3-RELEASE swift-5.4-RELEASE -- stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def [omochi@omochi-iMacPro swift (main=)]$ git diff swift-5.2-RELEASE swift-5.3-RELEASE -- stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def [omochi@omochi-iMacPro swift (main=)]$ git diff swift-5.1-RELEASE swift-5.2-RELEASE -- stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def [omochi@omochi-iMacPro swift (main=)]$ git diff swift-5.0-RELEASE swift-5.1-RELEASE -- stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def [omochi@omochi-iMacPro swift (main=)]$ git diff swift-4.2-RELEASE swift-5.0-RELEASE -- stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def [omochi@omochi-iMacPro swift (main=)]$ git diff swift-4.2-RELEASE [DRELEASE swift-5.0-RELEASE -- stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def [omochi@omochi-iMacPro swift (main=)]$ git diff swift-4.1-RELEASE swift-4.2-RELEASE -- stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def [omochi@omochi-iMacPro swift (main=)]$ git diff swift-4.0-RELEASE swift-4.2-RELEASE -- stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def [omochi@omochi-iMacPro swift (main=)]$ git diff swift-3.0-RELEASE swift-4.2-RELEASE -- stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def [omochi@omochi-iMacPro swift (main=)]$ git diff swift-3.0-RELEASE swift-5.0-RELEASE -- stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.defstdlib/public/CompatibilityOverride/CompatibilityOverride.def っぽいswift/stdlib/public/runtime/CompatibilityOverride.def-OVERRIDE_METADATALOOKUP(getTypeByMangledName, TypeInfo, , SWIFT_CC(swift), swift::, +OVERRIDE_METADATALOOKUP(getTypeByMangledName, TypeLookupErrorOr<TypeInfo>, , SWIFT_CC(swift), swift::, (MetadataRequest request, StringRef typeName, const void * const *arguments,git show swift-5.4-RELEASE:stdlib/public/runtime/CompatibilityOverride.def でタグ時点のファイルを抽出してdiff取りました[omochi@omochi-iMacPro swift (main=)]$ git diff swift-5.4-RELEASE:stdlib/public/runtime/CompatibilityOverride.def swift-5.5-RELEASE:stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def diff --git a/stdlib/public/runtime/CompatibilityOverride.def b/stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def index 1489ee07e1e..3c265c1e335 100644 --- a/stdlib/public/runtime/CompatibilityOverride.def +++ b/stdlib/public/CompatibilityOverride/CompatibilityOverrideRuntime.def @@ -1,4 +1,4 @@ -//===--- CompatibilityOverrides.def - Compatibility Overrides Database -*- C++ -*-===// +//===--- CompatibilityOverridesRuntime.def - Overrides Database -*- C++ -*-===// // // This source file is part of the Swift.org open source project // @@ -15,12 +15,14 @@ // //===----------------------------------------------------------------------===// -/// #define OVERRIDE(name, ret, attrs, namespace, typedArgs, namedArgs) +/// #define OVERRIDE(name, ret, attrs, ccAttrs, namespace, typedArgs, namedArgs) /// Provides information about an overridable function. /// - name is the name of the function, without any leading swift_ or /// namespace. /// - ret is the return type of the function. /// - attrs is the attributes, if any, applied to the function definition. +/// - ccAttrs is the calling convention attributes, if any, applied to the +/// function definition and corresponding typedefs /// - namespace is the namespace, if any, the function is in, including a /// trailing :: /// - typedArgs is the argument list, including types, surrounded by @@ -34,8 +36,10 @@ /// and OVERRIDE_KEYPATH to get only those entries. // NOTE: this file is used to build the definition of OverrideSection in -// CompatibilityOverride.cpp, which is part of the ABI. Do not move or remove entries -// in this file after ABI stability. Additional entries can be added to the end. +// CompatibilityOverride.cpp, which is part of the ABI. Moving or removing +// entries in this file will break the ABI. Additional entries can be added to +// the end. ABI breaks or version-specific changes can be accommodated by +// changing the name of the override section in that file. #ifdef OVERRIDE # define OVERRIDE_METADATALOOKUP OVERRIDEgit diff swift-5.1-RELEASE swift-5.2-RELEASE -- stdlib/public/runtime/CompatibilityOverride.def git diff swift-5.1-RELEASE swift-5.2-RELEASE -- stdlib/public/runtime/CompatibilityOverride.def git diff swift-5.2-RELEASE swift-5.3-RELEASE -- stdlib/public/runtime/CompatibilityOverride.def このへんもdiffゼロだけどセクション名更新されてますね-OVERRIDE_METADATALOOKUP(getTypeByMangledNode, TypeInfo, , SWIFT_CC(swift), swift::, +OVERRIDE_METADATALOOKUP(getTypeByMangledNode, TypeLookupErrorOr<TypeInfo>, , SWIFT_CC(swift), swift::, 5.4のこれは本当に返り値が変わっただけかOVERRIDE_METADATALOOKUP(getTypeByMangledNode, TypeLookupErrorOr<TypeInfo>, , SWIFT_CC(swift), swift::, (MetadataRequest request, Demangler &demangler, Demangle::NodePointer node, const void * const *arguments, SubstGenericParameterFn substGenericParam, SubstDependentWitnessTableFn substWitnessTable), (request, demangler, node, arguments, substGenericParam, substWitnessTable)) OVERRIDE_METADATALOOKUP(getTypeByMangledName, TypeLookupErrorOr<TypeInfo>, , SWIFT_CC(swift), swift::, (MetadataRequest request, StringRef typeName, const void * const *arguments, SubstGenericParameterFn substGenericParam, SubstDependentWitnessTableFn substWitnessTable), (request, typeName, arguments, substGenericParam, substWitnessTable))
1
1main.swift がある」に依存してビルドが制御されてるのがキモいという問題が解決するのか@Section(title: "") にするとクラッシュした Documentation/MyPackage.docc/// Converts: /// %extract = struct_extract %src : $TypeWithSingleOwnershipValue /// %copy = copy_value %extract : $OwnershipValue /// To: /// %copy = copy_value %src : $TypeWithSingleOwnershipValue /// (%extracted,...) = destructure %copy : $OwnershipValue (edited)/// For types with a single reference member, converts /// src -> struct_extract -> copy /// into /// src -> copy -> destructure // Delete a dead forwarded value before sinking to avoid this pattern: // %outerVal = destructure_struct %def // destroy %outerVal <= delete this destroy now // destroy %def <= so we don't delete this one later/// Because this algorithm rewrites copies and destroys without attempting to /// balance the retain count, it is only sound when SIL is in ownership-SSA /// form.// main sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 { bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>): %2 = metatype $@thick Cat.Type // user: %4 // function_ref Cat.__allocating_init() %3 = function_ref @$s4test3CatCACycfC : $@convention(method) (@thick Cat.Type) -> @owned Cat // user: %4 %4 = apply %3(%2) : $@convention(method) (@thick Cat.Type) -> @owned Cat // users: %22, %8, %5 debug_value %4 : $Cat, let, name "mike" // id: %5 %6 = alloc_box ${ var @sil_unowned Cat }, let, name "tama" // users: %21, %7 %7 = project_box %6 : ${ var @sil_unowned Cat }, 0 // users: %15, %12 %8 = begin_borrow %4 : $Cat // users: %14, %9 %9 = copy_value %8 : $Cat // users: %13, %10 %10 = ref_to_unowned %9 : $Cat to $@sil_unowned Cat // user: %11 %11 = copy_value %10 : $@sil_unowned Cat // user: %12 store %11 to [init] %7 : $*@sil_unowned Cat // id: %12 destroy_value %9 : $Cat // id: %13 end_borrow %8 : $Cat // id: %14 %15 = load_borrow %7 : $*@sil_unowned Cat // users: %17, %16 %16 = strong_copy_unowned_value %15 : $@sil_unowned Cat // users: %20, %19, %18 end_borrow %15 : $@sil_unowned Cat // id: %17 %18 = class_method %16 : $Cat, #Cat.meow : (Cat) -> () -> (), $@convention(method) (@guaranteed Cat) -> () // user: %19 %19 = apply %18(%16) : $@convention(method) (@guaranteed Cat) -> () destroy_value %16 : $Cat // id: %20 destroy_value %6 : ${ var @sil_unowned Cat } // id: %21 destroy_value %4 : $Cat // id: %22 %23 = integer_literal $Builtin.Int32, 0 // user: %24 %24 = struct $Int32 (%23 : $Builtin.Int32) // user: %25 return %24 : $Int32 // id: %25 } // end sil function 'main'
1
1
(edited)
1${product_name}_${module_name}.${class_name}
1a.components(separatedBy: "_") ですかね?productname_modulename が入ってそうだからそれでもいけますねa.components(separatedBy: "_") ですかね? このようにバッククォート3つ
このようにバッククォート1つ
@mt.hodaka こうやるといいですよ