func hoge<Foo: Protocol>(foo: Foo)
と、fucn (foo: Protocol)
だとstruct API { private init() { } struct Request { private init() { } struct GetDayOfWeekStories: APIRequest {
(edited)case
なし enum
だとどうやってもインスタンス化できないので、 private init 書く必要ないから いいんじゃないかと思ってます。private init() { fatalError() }
くらいにした方がいいかなと思ってました)/// Namespace for diagnostics enum diag {} extension diag { // メンバー群 ...
実際にはすべてのメンバーを extension に実装することにより、 case
を書けなくするということをやっています。 (edited)??
って、もしかしてコンパイルすごい遅いんでしょうか func apiErrorWithPromise(_ errorMsg: String? = nil, _ httpNumber: Int? = nil) -> Promise<Void>{ let errorMessage = "エラーメッセージ:\n"+(errorMsg ?? "不明なエラー(iMast)")+" ("+String(httpNumber ?? -1)+")\n\nエラーメッセージに従っても解決しない場合は、アプリを再起動してみてください。" return alertWithPromise( title: "APIエラー", message: errorMessage ) }
var errorMessage:String = "" errorMessage = "エラーメッセージ:\n" errorMessage += errorMsg ?? "不明なエラー(iMast)" errorMessage += " (" errorMessage += String(httpNumber ?? -1) errorMessage += ")\n\nエラーメッセージに従っても解決しない場合は、アプリを再起動してみてください。"
のようにしたら早くなりました、ありがとうございます\()
どうも個人的に読みにくいんですよねlet errorMessage
に +で連結して代入 let errorMsg2 = errorMsg ?? "不明なエラー(iMast)" let httpNumber2 = httpNumber ?? -1
String.localizedStringWithFormat("", a, b)
) 今回の場合、これだけで速くなりそう。 (edited) typealias DataSearchFlags : oneof { None, Backward, Anchored }
[default: ]
を指定するのは、値の存在が保証されてない場面では??dict[key]! += 1
ってできたっけ?dict[key] += 1
ができるかどうかはわからないけど、 それができないからといってdict[key, default: never()] += 1
こう?dict[key, default: undefined()] += 1
var x: [String: Int] = [:] x["aaa"] = 3 x["aaa"]! += 1 print(x["aaa"])
Optional(4)
!
演算子はオペランドが左辺値の場合、左辺値のままにしてくれるのか。dict[key]! += 1
で良いってことになるのか・・・?dict[key] ?? defaultValue += 1
dict[key] ||= 3
rubyだとこういうのよく見る (edited)func doubleQuestion( left: (read: ()->T?, write: (T)->Void), right: (read: ()->T, write: (T)->Void) ) -> (read: () -> T, write: (T) -> Void)
(edited)Neverがボトムになれba まどろっこしい関数用意しなくて良くなるんだがな
これおもしろいですね。dict[key, default: fatalError()] += 1
(edited)Never
がボトムタイプでない現状だと、 func never<T>(_ message: String = "") -> T { fatalError(message) }
みたいなのがいると。Never
がボトムタイプにならないのって誰も Proposal 書かないから?An uninhabited type can be seen as a subtype of any other type ... This can be considered as a separate proposal.
enum Never {}
がボトムってどうなの?とか、他の enum Foo {}
はどうなるの?とか、色々ややこしいから後回しにされてるのでは。+1
みたいなリプライあるけどwsomeFunc(AnyProtocol, parameter...)
的なのを考えてたんですが型で判別できるから、ありかどうかで迷ってる感じですdownload
は Alamofire.download
ですよね 正式にはSwift.min
ですdownload
でアクセスできるので 結局そこがどうなのかって話なわけですよねcom.omochimetaru.Alamofire.download
とかなってシンドイけど Alamofire.download
ならまあ別に平気だし、だいたいは引数の型でも区別可能だし。download
が出てきてごちゃごちゃしてきたときはfunc alamofireDownload() { .. }
とかを自作してラップするのが良いんじゃないでしょうかimport ... as ...
的なやつですかprotocol APIRequestable { func load<R: Request>(request: R) -> R.Response }
って感じですかね?requests<R: Request>(adapter: RequestAdapter=DefaultRequestAdapter()) -> (request: R) -> R.Response
みたいにしようかで悩んでました (edited)swiftc
が生成したhello_world.bc
のターゲットがx86_64-apple-macosx10.9
になってるからダメだよ、となってる。swiftc
でtarget
がasmjs-unknown-emscripten
な.bc
を生成できないとダメなんじゃないかな。emscripten
のissueには「asmjs-unknown-emscripten
はWebAssembly
(wasm32
)とほぼ同じだよね?」って話してる人がいて、同じ人がSwiftをWebAssemblyへクロスコンパイルする話題をswift-devに投げてる。 https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20170626/004860.html (edited)Promise
みたいに非同期処理とエラー処理をまとめて扱うような設計が嫌いで、非同期処理なら非同期処理、エラー処理ならエラー処理と責務を分解しておくべきだと考えて、エラー処理を含まない Promise
↓を作ってました。 https://github.com/koher/PromiseK/tree/dev-3.0Promise
と Result
が対応してるなと思って、それらを throws
, try
と (edited)async
, await
に対応させれば、自由にまぜて使えるよなぁと考えたものです。Promise
にエラー処理を担当させちゃうと、 catch
忘れがおこっちゃうんですよねぇ。Promise
と Result
を一緒に使うとモナドパズルになっちゃうんですよねぇ。Result<Promise<Result<Foo>>>
を Promise<Result<Foo>>
にしたいとか。Array<Promise<Result<Foo>>>
を Primise<Result<Array<Foo>>>
にしたいとか。let a: Promise<Int> = ... let b: Promise<() throws -> Int> = a.map { try foo($0) }
みたいに、 map
等の中で throw
される場合は戻り値の型パラメータを () throws -> Foo
に変換する API を考えてます。async
, await
ができれば無用の長物ですが。typealias Promise<Value> = (@escaping (Value) -> ()) -> ()
とする Promisure (= Promise + Closure) というライブラリも作ってましたw// Wrapping let a: Promise<Int> = { $0(3) } // like `Promise.resolve(3)` in JS // Promisifying a callback let b: Promise<Int> = promise { resolve in // Gets 5 after 1.0 seconds DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { resolve({ $0(5) }) } } // Operators let sum: Promise<Int> = a >>- { a in b >>- { b in { $0(a + b) } } } // flatMap let square: Promise<Int> = { $0 * $0 } <^> a // map let vector: Promise<Vector2> = curry(Vector2.init) <^> { $0(2.0) } <*> { $0(3.0) } // apply
Observable
にエラーが組み込まれてるのも僕は好みじゃないんですが、どうにかならないものでしょうか。throws
, try
みたいな特殊構文用意するよりも、モナドに対して do
記法用意するとかの方が汎用性はありますよねぇ。Result
と Promise
なら Promise
が外側にいてほしいとか、モナド感での precedence みたいなものが考えられる気がして、Monad
型に対して演算子みたいな precedence
を指定できてsort
関数みたいに、それを使って入れ子を関数が解決する。let a: Result<Promise<Int>> = ... let b: Promise<Result<Int>> = magic(a) do { let c: Int <-- b // 多段アンラップ let d: Result<Int> <- b // 一段アンラップ }
try
とかキーワード足さなくても自作モナドを組み込みモナドと同じように便利に使える。then
が map
と flatMap
になってるんですけど、ネストしてくると読みづらいんですよねぇ・・・。Result
を作らなかったから thorws
, try
を別の型でラップしたい場合に Promise<() throws -> Int>
とかなるのはちょっとつらいですよね。Observable
とかでやろうとしたらできないですよね?=>
レベルだと演算子の方が可読性高そうだけど。Any
でもダメで、任意の型パラじゃないといけないから辛い・・・extension Any { func `let`<T>(_ f: (Any) -> (T)) -> T { ... } }
Any
になっちゃってSelf
にする extension
ってできるんだっけ?public func =><T, U>(lhs: T, rhs: (T) throws -> U) rethrows -> U { return try rhs(lhs) }
class Animal {} class Cat : Animal { func nya() { print("nyaa") } } extension Animal { func exec(f: (Self) -> Void) { f(self) } } let cat = Cat() cat.exec { $0.nya() } error: TempGround.playground:11:12: error: value of type 'Animal' has no member 'nya' cat.exec { $0.nya() } ^~ ~~~
extension SomeProtocol where Self: SomeClass {}
(edited)extension Any where Self: SomeClass {}
protocol Anything {} extension Anything { func `let`<T>(_ f: (Self) throws -> T) rethrows -> T { return try f(self) } } extension Double: Anything {} (42.0).`let` { $0 + 1.0 / $0 }
protocol Proto {} class Cat : Proto { func nya() { print("nyaa") } } extension Proto { func exec2(f: (Self) -> Void) { f(self) } } let cat = Cat() cat.exec2 { $0.nya() }
=>
の議論からするとそれは問題ないのでは=>
の実装をオペレータからメソッドにできるかどうかだけを今考えていてAny
が nominal でないってことだけなわけだ。Self
を f
に渡す形で実装はできる。Any
じゃなくてLettable
という protocol
のメソッドとして作って.let
を使いたい型については extension Cat : Lettable {}
=>
の方がいいと思う。<$>
は順番が逆転しちゃう問題もありますしねぇ・・・Promise
のチェーンはpromise.flatMap { ... }.flatMap { ... }.flatMap { ... }
primise >>- { ... } >>- { ... } >>- { ... }
=>
は標準ライブラリに入れてほしい・・・。r'''
出せなかったし嘘だと思うr'''
は正規表現じゃなくて生マルチライン文字列Swift >>-
で検索したら、一つ目は https://www.apple.com/jp/swift/ だけど、二つ目は typelift/Operadics で、三つ目は thoughtbot/Runes だった。<^>
も駄目っぽいですよ>>=
は重複してるから >>-
に、 <$>
は言語仕様上の制約で <^>
になってる。haskell <$>
は https://stackoverflow.com/questions/37286376/what-does-mean-in-haskell が出たからEither<T, Either<U, V>>
public enum Either2<A, B> { case a(A) case b(B) } public protocol Either2Convertible { associatedtype CaseA associatedtype CaseB var asEither: Either2<CaseA, CaseB> { get } } extension Either2: Either2Convertible { public var asEither: Either2 { return self } }
enum
の抽象化ってことは、 Either2<Int, String>
と Either2<String, Int>
は区別したいってことですよね?Enum2
, Enum2Convertible
は良さそうEnum1
と Enum0
もいらないですか? Box
と Never
Enum3
とかだと CaseA
より Case1
とかの方がよさそうenum Enum2<T0, T1> { case Case0(T0) case Case1(T1) }
EnumN
とか?Houyhnhnm 音節Hou・yhn・hnm 発音記号/hwínəm|húːɪ‐/ 名詞可算名詞 フーイナム 《Swift 作 Gulliver's Travels (ガリバー旅行記)の中の人間的な理性が徹底している馬; 人間の形をした Yahooを支配する》. [馬の鳴き声からのSwiftの造語]
swift package init
したときに面倒$ swift package init --help OVERVIEW: Initialize a new package OPTIONS: --type empty|library|executable|system-module
Yahoo!の名前の由来は英語の「Yet Another Hierarchical Officious Oracle」(さらにもう一つの階層的でお節介な神託)の略だといわれている[57]。また、ファイロとヤンは自分たちのことを「ならずもの」だと考えているので、「粗野な人」という意味がある「Yahoo」(『ガリヴァー旅行記』に登場する野獣の名前が由来)という言葉を選んだと主張している[10]。さらに感嘆符が付いていることに関しては「ヤッホー!」「やったー!」を意味する英語の感動詞「yahoo」と掛けているとも考えられる。
EnumNConvertible
を EnumN
に convert するんじゃないんですか?CustomStringConvertible
とかを考えても EnumNConvertible
とかならおかしくない気も。$ gyb -D Key=Value
でパラメータ渡せるから、できるよpublic func animatedItems<S: AnimatableSectionModelType, O: ObservableType, C0: Reusable, C1: Reusable, C2: Reusable, C3: Reusable, C4: Reusable>(for type0: C0.Type, _ type1: C1.Type, _ type2: C2.Type, _ type3: C3.Type, _ type4: C4.Type) -> (O) -> Disposable where C0: UICollectionViewCell , C1: UICollectionViewCell , C2: UICollectionViewCell , C3: UICollectionViewCell , C4: UICollectionViewCell , S.Item: Enum5Convertible , S.Item.T0 == C0.Dependency , S.Item.T1 == C1.Dependency , S.Item.T2 == C2.Dependency , S.Item.T3 == C3.Dependency , S.Item.T4 == C4.Dependency , O.E == [S] {
使う側がこんな感じの地獄じみた形相になってるから、任意個数サポートできるのはもはや必須の感じがするdataSourceObservable .bind(to: tableView.rx.animatedItems(for: MyCell1.self, MyCell2.self)) .disposed(by: disposeBag)
curry
は昔ジェネリック引数14個(?)でコンパイル終わらなくなる問題がありましたが大丈夫そうですか?--line-directive=
入れないと ###sourceLocation
が各行入るからなんなのかと思った!!
オペレータ。機能は !
と同じ。Codable
を適用すると、encode/decodeを実現するための実装をコンパイラーが生...struct ObservableA<T> { func subscribe(onNext:(T) -> () = { _ in }) { } } ObservableA<(Int, Int)>().subscribe(onNext: { (a, b) in // ok }) struct ObservableB<T> { func subscribe(onNext:((T) -> ())? = nil) { } } ObservableB<(Int, Int)>().subscribe(onNext: { (a, b) in // 死ーん })
[omochi@omochi-iMac bin]$ pwd /Users/omochi/work/swift-source/build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/bin [omochi@omochi-iMac bin]$ ./swift --version Swift version 4.0-dev (LLVM a15decabe3, Clang 60a12bf739, Swift fcd389b17e) Target: x86_64-apple-macosx10.9
XCTest
にXFAIL
欲しいlit
はテキストファイルならなんでも良いので、.md
にテストを書いたりできるのが面白いと思った。 https://github.com/apple/swift-integration-tests/blob/master/swift-package-init-exec.mdlit.cfg
で指定すればですね。 https://github.com/apple/swift-integration-tests/blob/master/lit.cfg#L56XCTAssertEqualWithAcuracy
はフィールドごとに確認するので増えるほど書くのがきつくなる stcuct Hoge { val a: Float } let x = Hoge(a: 0) let y = Hoge(a: 0) XCTAssertEqualWithAcuracy(x, y, accuracy: 1e-10)
かといって関数に切り出すとXCodeで停止地点が分かりづらくなる。 XCTAsserEqual
はEquatable
を実装するだけで使えるので 同様にNealyEquatable
みたいなプロトコルを切ってXCTestがそれを使うXCTAssertEqualWithAcuracy
を用意してくれるのがベストかな。swift test
とかで結構密接に結びついてるのでこちらからどうこうもしにくい気が。かといって関数に切り出すとXCodeで停止地点が分かりづらくなる。
切り出した関数に…file: StaticString = #file, line: UInt = #line)
とかつけると良いのでは。QuickSpec
が(間接的に) XCTestCase
を継承してるのか。 https://github.com/Quick/Quick/blob/cd89737d3d5306124e91c357b66cde274a3269b4/Sources/Quick/QuickSpec.swift#L13swift test
もできるのかな?swift test
Package.swift
はdependenciesがなんか複雑になってますね……Quick
を使いたいからじゃない? < 複雑XCTestCase
を継承してる https://github.com/Quick/Quick/blob/cd89737d3d5306124e91c357b66cde274a3269b4/Sources/QuickSpecBase/include/QuickSpecBase.h#L8testDependencies
がなかったので、テストの時だけ使う依存を実現してる。testDependencies
見た気がしてたんだけど使えなくなってるのか・・・Remove testDependencies from PackageDescription This feature was supposed to support dependencies only for the root package but at some point it stopped working however the API still remained open. This patch removes the public API. This is a valid and desired feature which is supposed to come back after it goes through proper review on swift evolution.
https://github.com/apple/swift-package-manager/commit/34b7826cb586b0769ea5f60a7718d7de599ce27fPackage.swift
を用意してたけど、環境変数で切り替えられることをikesyoさんに伝えたら使ってくれた。 (edited)Package
の dependencies
がテストからも使えるのなんか変な気も。> SWIFTPM_TEST_Carthage ああこれはSPMが定義してくれるのか。
Makefileで実行するときに設定してます。 https://github.com/Carthage/Carthage/blob/master/Makefile#L82Package.swift
がサンドボックス内で解釈される際に、SwiftPMがあえて環境変数を引き継ぐ様にしてるので、あながち間違いでもない。$ which -a sandbox-exec /usr/bin/sandbox-exec
DESCRIPTION The sandbox-exec command is DEPRECATED. Developers who wish to sandbox an app should instead adopt the App Sandbox feature described in the App Sandbox Design Guide.
sandbox-exec
を使う様にしたコミットには環境変数がらみが特に書かれてないぽいから「環境変数をあえて渡す」というのは、チャットの中だけの話だったかも。#line
を使うってこれのことですか。 http://masilotti.com/xctest-helpers/ そもそもrecordFailure
の存在を知らなくてログに行番号出るだけじゃ分かりにくいとか思っていました。XCTAssert*()
シリーズにも渡せます。XCTAssert*()
シリーズに渡せるってのは何でしょう? recordFailure
がXCTestCase
のメソッドなのでXCTAssert*()
のようにトップレベルのを定義するにはデフォルト引数で呼び出し元のself
を渡すとかするのかなぁと思ったのですが。self
を渡す話をよく覚えていない……XCTestCase
は引数にないのでどこから渡っているのか謎。 別の仕組みになっているんだろうか。recordFailure
はXCTestCase
のメソッドなんですよ。 で、XCTAssert*()
はトップレベルなのでrecordFailure
が使えない(はず)XCTestCase
のextensionにすればいいんですが XCTAssert*()
と同名を用いると例のバグ?でトップレベルのほうが見えなくなる。 (edited)recordFailure()
ではなく XCTFail()
を使ってました。 https://github.com/realm/SwiftLint/blob/master/Tests/SwiftLintFrameworkTests/IntegrationTests.swift#L35recordFailure
を使うんじゃなくて内部でfile, line指定付きのXCTAssert*()
を使えってことですね。 間違った方向に進んでました。enum Foo { static var foo: Foo { fatalError() } } func bar(_ foo: @autoclosure () -> Foo, ....) { ... } bar(.foo, ....)
これが可能になるFoo.foo
が実際には生成されないのがポイント?delegate.scrollView(scrollView, .didScroll)
とかにいいかも (edited)struct Foo {} let foo = Foo() func bar(foo: Foo, ....) { ... } bar(foo, ....)
そもそもこれじゃ駄目な理由は?struct Foo { static var foo = Foo() }
ならまあ差はそれほど無いのかもしれない。.foo
で書けるねstruct BarOverloads { static let foo = BarFoo() static let poo = BarPoo() } func bar(_ overload: BarFoo, ...) func bar(_ overload: BarPoo, ...) bar(.foo, ...) // できない bar(.poo, ...)
(edited)struct Bar { struct Foo { static let foo = Foo() } struct Poo { static let poo = Poo() } } func bar(_ overload: Bar.Foo, ...) func bar(_ overload: Bar.Poo, ...) bar(.foo, ...) bar(.poo, ...)
(edited)\
を使う感じで。 https://github.com/apple/swift-evolution/blob/master/proposals/0182-newline-escape-in-strings.md (edited)let s = """ ... In Windows you have paths like C:\ ... """
\
を \\
に直さないといけないけど、新使用だとコンパイルエラーにならないから問題だと。特に """
だからといって文字列コピペしてきたときとかに問題起こりそう。c:\news
とかもそうなんで。ちょっと弱い。Optionalのclosureでtupleが分解できない問題治してもらえた。はやいw
swift-4.0-DEVELOPMENT-SNAPSHOT-2017-07-11-a
以降で直ってるぽいですね。struct
でもサイズが大きいと勝手に最適化されたりするんでしょうか?どこかで触れられてましたっけ? https://developer.apple.com/videos/play/wwdc2017/402/std::string
は確か COW だったけど COW 止めたんよね?Array
等の場合はマルチスレッドをサポートしないことで問題を回避している??var a = [2, 3, 5, 7] // スレッドA a[2] = 4 print(a) // スレッドB a[3] = 8 print(a)
(edited)startThread( closure: () -> Void )
var a = [2, 3, 5, 7] a[2] = 4 startThread { a[3] = 8 }
func startThread(f: @escaping () -> Void) { f() } func main() { var a = [2, 3, 5] a[0] = 88 startThread { a[1] = 99 } print(a) // [88, 99, 5] } main()
struct
である Array
に包まれてるからvar a = 2 let foo: () -> () = { a += 1 } foo() print(a) // 3