willDisplayCell
で cellHeights
を更新して、 estimatedRowHeightAtIndexPath
で読み出すからdelegateメソッドでしか使われてないよね、という話ではなく?class HogeObj { }
が書いてあるファイルでのみHogeObjのextensionにstored propertyを持たせられるようになったらな〜という話。これだったらUIKitのクラスに対してextensionでstored property足せない
// MARK: --
で分けるのはどうかと思ったけど、 protocol conformanceが一番上に集まっちゃうから微妙かな (edited)interface Base { fun print() } class Derived(b: Base) : Base by b
b
は Base
型のフィールドで、 Derived
が Base
に conformさせるのを by b
で指定してる。class
の右にしか書けないけど、 Swiftなら conformanceがそもそもextensionに書けるわけだからextension UserStatusViewController : UIScrollViewDelegate by scrollViewDelegateMixIn {}
scrollViewDelegateMixIn
は UserStatusViewController
の storedProperty名で struct ScrollViewDelegateMixIn : UIScrollViewDelegate
という型がついてる想定。 (edited)class { }
の中に書かないといけないならkotlinみたいに上のところでもいいのかなextension ViewController { class ScrollViewDelegate: UIScrollViewDelegate { //ここに実装 } }
だけどこれでも、ViewController.ScrollViewDelegateの宣言は本体側にないといけないよね、そこは解決しないのでは。まあすっきりはするか。var scrollViewDelegate: ScrollViewDelegate
をどこに書くの?と言う問題は残っているtableView.delegate = self
の右辺が self
じゃなくてもいいじゃんって事かclass ScrollViewDelegate: NSObject, UIScrollViewDelegate { weak var parent: ViewController? }
とかでまあおおよそ問題はないはず.delegate =
なケースだけで (edited)let a = 3
let a = 3
class C { p: number; // Should be an error under --strictNullChecks method() { this.p; } }
--strictNullChecks
は このようなコンストラクタでのフィールドの初期化忘れに対して何も検査しないため 簡単に undefined
を踏むのだ (edited)private struct Hoge {} fileprivate struct Hoge {}
これが一番モニョいclass Cat { var a: String { didSet { // 呼ばれない print("nyaa") } } init() { self.a = "a" } } Cat()
@here 知ってた?T?
へのキャストはされない事がわかった。 T
と T?
両方行けるときは T?
になることがわかった。T?
になることから、 T
では駄目になる事を検証しているという仮説は成り立たなかった。 T
と T?
の倍々で増えていくという仮説についても、 4倍で増えていくことから成り立たなかった。T?
への暗黙キャストはしない。.hoge()
ってドット構文になった時点で Int
しか試されない。func commonIntFunc(_ x: Int?) -> Int {...} func commonIntFunc(_ x: Int!) -> Int {...}
この2つは共存出来ないのか機種名: MacBook 機種ID: MacBook8,1 プロセッサ名: Intel Core M プロセッサ速度: 1.3 GHz プロセッサの個数: 1 コアの総数: 2 二次キャッシュ(コア単位): 256 KB 三次キャッシュ: 4 MB メモリ: 8 GB
機種名: iMac 機種 ID: iMac17,1 プロセッサ名: Intel Core i7 プロセッサ速度: 4 GHz プロセッサの個数: 1 コアの総数: 4 二次キャッシュ(コア単位): 256 KB 三次キャッシュ: 8 MB メモリ: 32 GB
time
コマンドの real
を張ってる。1回しかやってないし他の作業も止めてないからだいぶガバガバだけど。 (edited)~ (๑˃̵ᴗ˂̵)ﻭ < time swiftc compile.swift -o compile swiftc compile.swift -o compile 15.78s user 0.30s system 99% cpu 16.137 total
this
が使えないためサブクラスのフィールドを埋める前に親クラスのコンストラクタが呼ばれる 厳しさ2. サブクラスのコンストラクタ内部で呼ばれた親クラスのコンストラクタにおいてメソッドを呼び出すと、それがサブクラスでオーバーライドされている場合、サブクラスの実装が呼ばれる これらの組み合わせによって、フィールドが未初期化のサブクラスのメソッドが呼ばれて、 undefined
を踏む。 下記はその問題によって、純粋なJSユーザーが困っている事例2件 http://stackoverflow.com/questions/32615034/call-parent-function-which-is-being-overridden-by-child-during-constructor-chain
http://stackoverflow.com/questions/32449880/parent-constructor-call-overriden-functions-before-all-child-constructors-are-fiprivate
と、構文スコープになった scoped
に再び分裂する、みたいな流れになったら草private
ですよねえ。/** * Calls the specified function [block] with `this` value as its argument and returns its result. */ @kotlin.internal.InlineOnly public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
=>
演算子でSwiftに導入すると、次のような事ができる// こんな関数があったとして func hogehogeFunc(str: String, int: Int) -> String { return "" } // こんなStructがあったとして struct Cat { var name: String var age: Int } // こんな関数が合ったとして func createPrettyCat() -> Cat { return Cat(name: "mike", age: 2) } // 従来は・・・ func demo1() { let cat = createPrettyCat() let result = hogehogeFunc(str: cat.name, int: cat.age) print(result) } // こういうのがシュッと1行にできなくて萎える // 提案のもとでは・・・ func demo2() { print(createPrettyCat() => { hogehogeFunc(str: $0.name, int: $0.age) }) } // 左から右にシュ〜っとかける
=>
の方がいい?->>
より ダブルアローのほうが 打ちやすくていい =>
式の評価結果はクロージャの結果そのものだから、hoge => { $0.piyo } => { $0.fuga }
Any
に extension でメソッド生やせないから諦めてた。let
メソッドと同じ順序で書ける。class Cat attr_accessor :name, :age def initialize @name = "mike" @age = 3 end end p Cat.new.tap {|x| x.age } # => #<Cat:0x007f1790eb9b60 @name="mike", @age=3>
Rubyのtapは確かに違った。。 (edited)dependencies: [ .Package(url: "https://github.com/koher/swiflet.git", majorVersion: 0) ]
(edited)tap:
method for Objective-C borrowed from Ruby.func fastUnwrap<T>(_ arg: T!) -> T? { return arg }
(edited)return arg
として出現していますがclass Outer<T> { static var staticVar: T class Inner { static var staticVar: T } }
Outer<Int>.staticVar = 3 Outer<String>.staticVar = "abc" Outer<Int>.Inner.staticVar = 4 Outer<String>.Inner.staticVar = "xyz"
error: static stored properties not supported in generic types static var staticVar: T
CatInt, CatString
は static contextが2つあるけど、 Cat<Int>, Cat<String>
は1つしか無いんだなlet a = 42 a.map { $0 } // error
(edited)Any?
に map
を生やしてみたら、 List
の map
が正しく動かなくなって大変なことに。T?
への暗黙の型変換は起こる場合と起こらない場合が使い分けられていることに気付きました。.
の左側では暗黙の型変換をしないだけかもですが。.
の左って暗黙変換すると非決定性が高すぎて実現不可能な気がするんですがpublic class Main { public static void main(String[] args) { System.out.println(2.compareTo(3)); } }
$ javac Main.java Main.java:3: error: ')' expected System.out.println(2.compareTo(3)); ^ Main.java:3: error: not a statement System.out.println(2.compareTo(3)); ^ Main.java:3: error: ';' expected System.out.println(2.compareTo(3)); ^ 3 errors
a
を int
に変えたらダメ。 public class Main { public static void main(String[] args) { Integer a = 2; System.out.println(a.compareTo(3)); } }
let
みたいな Any
由来のメソッドは使えるけど、それは暗黙の型変換なく使えるんで。foo?.let { x -> bar(x) }
map
かつ flatMap
になります。?.let { }
はアツいよねmap
を生やしてみたら、という話なので、実用上は問題ないです。Promise
の.then
みを感じるAnything
: Null
= Kotlin : Any?
: Nothing?
の話を整理して Qiita に書きたい。 (edited)typealias Anything = Any? typealias Null = Nothing?
とすれば Ceylon と同じになる。typealias Object = Any
これもいるか。Never
が bottom type になるかもという話も興味深い。IMO, if we accept a single error type per function, there could be a simpler model for this. We could say that the `throws` type is a generic parameter of all function types, and it defaults to the uninhabited `Never` type for functions that don't throw. () -> () == () throws Never -> () () throws -> () == () throws Error -> () In this model, you'd get many benefits: - `rethrows` could become first-class, reducing down to just polymorphic `throws`: func foo(_: () throws -> ()) rethrows // Swift 3 func foo<T: Error>(_: () throws T -> ()) throws T // Swift X
Never
が bottom type でないと辻褄が合わない。rethorws
がただのシュガーになっちゃって、 reasync
との対応の解釈が難しいです・・・。 https://gist.github.com/koher/df007741788cb197d65b6babe2acf480actor
も Swift 5+ って書かれてるし、 4 ではない気がしてます。 http://researcher.watson.ibm.com/researcher/files/us-lmandel/lattner.pdf public class func Package(url: String, versions: ClosedRange<Version>) -> Dependency { return Package(url: url, versions: versions.lowerBound..<versions.upperBound.successor()) }
a...b
と a..<b
の両方に対応しようとすると、 a...b => a ..< b.successor()
の変換をオーバーロードの内側でやらないといかんのか。protocol Sequence { associatedtype Iterator : IteratorProtocol ... associatedtype SubSequence : Sequence // currently ill-formed, but should be possible }
シーケンスのサブシーケンスはシーケンス、としたいけど現状はできない、とかがあるらしいprotocol Eq { static func (a: Self, b: Self) -> Bool }
↑これはできるけど protocol EqX { associatedtype X static func (a: X, b: X) -> Bool } struct Hoge : EqX { typealias X = Hoge }
これはできない? (edited)protocol EqX { associatedtype X static func (a: X, b: X) -> Bool } protocol EqSelf { typealias X = Self } struct Hoge : EqSelf { }
これが駄目なのかな?protocol EqX { associatedtype X static func (a: X, b: X) -> Bool } struct Hoge : EqX { typealias X = Self }
HogeじゃなくてSelfか (edited)protocol A { associatedtype B } class C: A { typealias B=Self }
↑できないself
式の型が Self
だし。protocol HasB { associatedtype B } protocol A: HasB { } class AnyAs: HasB { typealias B = AnyAs.Type } class AnyA<T>: AnyAs where T: A { typealias B = T.B } class C: A { typealias B = C } AnyA<C>.B.self
class D: C {}
と書いたらどうなりますか?xs.map {|x| y = f(x) y ? [y] : [] }.flatten(1)
let error: MyCustomError = MyCustomError()
にしたらどうなるの?.
の左の暗黙の型変換ですかw
swift package pin --enable-autopin
), although package project owners can choose to disable this if they wish to have more fine grained control over their pinning behavior.$ cd a $ swift build $ .build/debug/a
let a = F<O>() print(a.f())
import GlibC
したとき何が使えるのかさっぱりわからん (edited) var fileActions: posix_spawn_file_actions_t? try PosixError.run { posix_spawn_file_actions_init(&fileActions) } defer { try PosixError.run { posix_spawn_file_actions_destroy(&fileActions) } }
foo() defer { bar() } return baz()
は foo() let r = baz() bar() return r
と等価だと思ってた。foo() return baz() bar()
こう考えると、throwできないわけだdefer
で try
できないのは↓書いてるときに遭遇して、できてもいいのになぁと思った。 http://qiita.com/koher/items/e4c1d88981291c35d571swift func foo() throws -> String { ... } // Java のような `throws` 節
```swift...close
できないことがありえないならそもそも throws
である必要ないんじゃ?
public static func run(proc: () -> Int32) throws { let code = proc() guard code == 0 else { throw PosixError(code: code) } }
こういうユーティリティだから try! PosixError.run { posix_spawn_file_actions_destroy(&fileActions) }
try! になるlet ret = posix_spawn_file_actions_destroy(&fileActions) fatalError(ret == 0, PsoxiError(code: ret).description)
(edited)ret
がスコープ汚染しちゃって、同じような処理を他にも書く必要があるから、これは採用できない。>=
は rethorws
にしないといけない気がしてきた。fatalError(ret == 0, PsoxiError(code: ret).description)
0判定、PosixErrorで包む、descriptionを呼び出す、などが冗長 try! PosixError.run { posix_spawn_file_actions_destroy(&fileActions) }
これならそのいずれもなくなっていて、同じことをする上で無駄が無い>=
はrethrows
じゃないとダメですねextension NSString { open func components(separatedBy separator: String) -> [String] @available(iOS 2.0, *) open func components(separatedBy separator: CharacterSet) -> [String] }
.
の!!左側で!!!import Foundation extension NSString { func piyo() -> Int { return 33 } } let a: String = "abc" a.piyo()
_SwiftBridgeable
が気になる感// // util.swift // RuString // // Created by omochimetaru on 2017/03/31. // // internal func findSubArray<C: Collection, I>( array: C, index: I, target: C ) -> I? where I == C.Index { var i: C.Index = index while i < array.endIndex { if matchArray(array1: array, index1: i, array2: target, index2: target.startIndex, length: target.distance(from: target.startIndex, to: target.endIndex)) { return i } i = array.index(after: i) } return nil } internal func matchArray<C: Collection, I, D>( array1: C, index1: I, array2: C, index2: I, length: D) -> Bool where I == C.Index, D == C.IndexDistance, C.SubSequence.Iterator.Element : Equatable { if array1.index(index1, offsetBy: length) >= array1.endIndex { return false } if array2.index(index2, offsetBy: length) >= array2.endIndex { return false } let test1 = array1[index1..<array1.index(index1, offsetBy: length)] let test2 = array2[index2..<array2.index(index2, offsetBy: length)] for (x1, x2) in zip(test1, test2) { if x1 != x2 { return false } } return true }
C.Index
って書いてたんだけどinternal func findSubArray<C: Collection>( array: C, index: C.Index, target: C ) -> C.Index? { var i: C.Index = index while i < array.endIndex { if matchArray(array1: array, index1: i, array2: target, index2: target.startIndex, length: target.distance(from: target.startIndex, to: target.endIndex)) { return i } i = array.index(after: i) } return nil } internal func matchArray<C: Collection>( array1: C, index1: C.Index, array2: C, index2: C.Index, length: C.IndexDistance) -> Bool where C.SubSequence.Iterator.Element : Equatable { if array1.index(index1, offsetBy: length) >= array1.endIndex { return false } if array2.index(index2, offsetBy: length) >= array2.endIndex { return false } let test1 = array1[index1..<array1.index(index1, offsetBy: length)] let test2 = array2[index2..<array2.index(index2, offsetBy: length)] for (x1, x2) in zip(test1, test2) { if x1 != x2 { return false } } return true }
where C.SubSequence.Iterator.Element : Equatable
を付ける必要があった