Kotlin 2
■ このスレッドは過去ログ倉庫に格納されています
>>290 ペーストに失敗したorz var value by { initValue() } >>291 自分はスタートブックを推す。 Javaを知っていることを前提としない入門書の存在を自分は知らない。 >>292 慌てて修正したらlazy落としていたorz orz var value by lazy { initValue() } 連投申し訳ない。これで違っていたら目も当てられんが、それもすみません。と誤っておきます。 >>291 Kotlinスタートブック -新しいAndroidプログラミング、長澤 太郎、2016 一番良いもクソも無い。 この1冊しか出ていないだろ アスペは質疑応答解説に使えねーなーもう >>288 なぜlateinitを使うかというと「初期値というものがうまく定義できなくてうまく初期化できないから」だ ※実際にはjavaでprimitive typeであるものはnull代入できないからという理屈なのだが知らなくていい Intとかは0とか-1とかで初期化できるだろ、最初にvarで0や-1入れとけ Nullableもnullで初期化できるからlateinit使わずにただのvarでnull入れとけ で、どーしても遅延初期化を使いたいなら var value: Int by Delegates.notNull<Int>() とか書くと形式上遅延初期化になる。むろん二度手間だが、遅延初期化という目的は一応達成される こんなごっついことせずに素直に0とか入れておいたほうがいいんじゃねーかなと思った感覚は正しい。0入れとけ0 あとはちらっと出てたけどby lazyで val value: Int by lazy { initValue() } と書くことでも一応達成される。こっちだとvalで書けるので好まれることが多いみたいだね 長澤太郎の本に書いてあるけど、 lateinit は、DI(Dipendency Injection)か、ユニットテスト時か、 フレームワークが自動的に初期化すると、不都合な場合に使う >>306 でもCの方が有力って書いてあるね。Cは何で増えんたんだろう。 >>308 デフォルト値はコンパイラが定義参照してるだけで、 型にもインスタンスにも持って無いから変数に入れた時点で使えないよ fun f1(n: Int=1) { print(n) } val f2 = ::f1 f1() //OK f2() //コンパイルエラー Cが必要なレベルの仕事の割合自体は 減ってるはずなのに…謎だ Cでググってもノイズが拾われてくる率が高い 他のCと間違われてるんじゃないのか Cの半分はC++という時代があったからな Cの半分はC#とC++ということでも不思議はない C sharpならC#確定なのだが C++はcocos2dやUnrealでのゲーム開発とかあるけどCはなんだろうな 廃れることはあり得ないけど 機械学習とかロボティクスとか自動運転とかがメディアで取り上げられるようになって学生にプログラミングへの関心がいっそう高まって教育現場での採用が増えてるのかもしれないな 就職にも有利なスキルだろうし もともと人気の高い言語だし本格的なプログラミングの登竜門的な立ち位置の言語でもあるし 検索エンジンで+"C programming" で検索した結果参照してるだけだからな 単にデータとしてうんこオブうんこだ githubやstackoverflow読んでるIEEEのランキングのほうがなんぼかマシ Javaの無名スコープを表す構文が無いことから調べていってみたけど 色々と良く設計されてると感心した 構文が無い代わりにrun関数がある ラムダ生成コストやブロック内でのreturnが気になったけど inline関数に渡すラムダはそれごとインライン化されるため コストも無くreturnはちゃんと呼び出し元関数から抜ける そうするとinlineでない関数にラムダを渡す場合のreturnとで 区別出来なくて危険かと思ったけど inlineでないラムダではラベル無しreturnが禁止されていた returnにラベル必須だと面倒ではと思ったけど 最後のステートメントが戻り値になる仕様だからむしろ楽だった ■Java int f(){ { String a = "a"; if(a.length() < 10){return 1;} // fから抜ける } return 2; //ここには来ない } ■Kotlin fun f(): Int { run { val a = "a" if(a.length < 10){ return 1 } // runでなくfから抜ける } return 2 //ここには来ない } fun fcall(f1: () -> Int): Int = f1() fun f(){ val a = fcall { val a = "a" if(a.length < 10){ return@fcall 1 } //ラベル付き else { 2 } //returnキーワード無し } } マップの値を条件判定に使いたいんだけど、Nullableをどう扱って良いのかわからない... val map = mapOf<String,Boolean>("hoge" to false,"fuge" to true,"piyo" to false) // ↓こんな感じで書きたいが、Nullableなので怒られる if (map["hoge"]){/*処理*/} //---------- 解決策 ---------- // @強制的に!!でNotnullにする。でもなんか気持ち悪い。 if (map["hoge"]!!){/*処理*/} // Aエルビス演算子を使う。しかし、IDEからBの書き方を提案される if (map["hoge"] ?: false){/*処理*/} // B凄いバカっぽい。ていうか、これOKで一番上ダメなんだ... if (map["hoge"] == true){/*処理*/} なんか、どれもしっくりこない。どうするのが正解なの.... 誰か教えて!お願いします! if (map.getOrDefault("hoge", false)) { ... } とか。 うーん。なんか変だね。mapOf では nullable かどうか判定しているのに get 時には nullable かどうかの情報が抜け落ちているような。 >>322 1はmap["hage"]とか存在しないキー指定すると落ちるだろ 2はエルビスで落ちないようになってて 3が落ちないのは、 ここ https://kotlinlang.org/docs/reference/equality.html Structural equality あたりに書いてある仕組みのせいかな どうmapを使えばいいのかは知らん 知らんが、kotlinみたいな言語だとキーが無いときの処理を適当にごまかすわかにはいかんだろ >強制的に!!でNotnullにする。でもなんか気持ち悪い。 >if (map["hoge"]!!){/*処理*/} そもそも、map は、そのキーが存在しない場合もあるのが、当たり前だろ。 そのキーが存在するかどうかを、チェックするメソッドもある 君が仕様・設計を考えるんだ。 1. そのキーが存在した場合の処理と、 2. 存在しなかった場合の処理 初心者は、強制変換の使い方をわかっていないのだから、!! を使うな >>325 +1 「知らないキーでmapに問い合わせたときの結果はnullになることがある」問題をコード的になんとかする必要がどうしてもある これは本当にどうしようもないので、どっかでKotlin(実際にはIDE)に知らせる面倒を許容するしかない ポイントとしては面倒でも一旦変数にぶち込むこと。これですべてうまくいく // checkNotNullの書き方だけ覚えればいいので最近全部これで書いてる val mapValue: Boolean = checkNotNull(map["hoge"]){ "map does not have key:<hoge>" } if (mapValue) { doSomething() } // またletをそんな用途に使って map["hoge"]?.let{ doSomething() } // 考え方がJavaっぽい(偏見)変数に入れないとnullチェックした履歴保持できないよ val mapValue = map["hoge"] if (mapValue!= null && mapValue) { doSomething() } // ほら、Kotlinの人はなんでもかんでもwhenで書きたがるから when(map["hoge"]){ null -> println("ぬるぽ") // なくても動く true -> doSomethingTrue() false -> doSomethingFalse() } 寝起きで書いたら!=がくっついた if (mapValue != null && mapValue) { doSomething() } まだ頭寝てるので動作チェックしてないから細かいとこは適当に直したりしてくれ >>326 安易に nullableValue?.let{ ... } を使って欲しくないのも似たような感じ 今回で言うと現在のmapに"hoge"が登録されていることの保証はどうするんだろうと思う ぬるぽ出ると追うのもしんどいわけでさ 1行で済むし動作にも影響らしい影響はないんだから脳死状態で checkNotNull(...){ "やべえhoge登録されてねえ" } とか書いとくのおすすめしたいわ map, hash は、集合の概念だから、 集合A に属するか属さないか、のどちらかの状態をとる 1. そのキーが集合A にあれば、値が取得できる 2. そのキーが集合A になければ、値が取得できない 1, 2 で、君がどういう処理をするか、仕様・設計を決めるのは君! Bがバカっぽいと感じるのは 真偽値 == 真偽値 だと勘違いしているから 実際には2つのNullableTypeの等値比較 if(map.getValue("hoge")){/* 処理 */} これで基本的にキーが存在しないと例外に行くしシンプルだね 直感的にはおかしく感じるな。(最初結果見た時は驚いたw) https://paiza.io/projects/zLCe3AYlPO9luQp7z2NaIw しかしクラスの参照同士の比較なのでこれで良い。 322です。 こんな速くレスいっぱい貰えるとは....皆ありがとう! 基本的にNullチェックは必須なんだね >>331 そういうことか!あくまで等値比較なのかー >>327 >感が方がJavaっぽい これやったんだけど、あんまりキレイな感じしないし、何よりJavaっぽくて.... >>332 そのメソッド知らなかった。使ってみます。 >>333 おかしく感じたのはprintln("True")と書いたからじゃないの not False と True は同義でないよ https://paiza.io/projects/1WgctVAqXu8SWmlIYtx4YA おまえがそう思うのならそうなのだろう。おまえの中ではな。 >>335 not false が true でない? じゃあなに? >>337 このコードだとFalse以外のAnyでは >>337 >>333 と>>335 のコードが示すように Nullable(null)もStringも真偽値ではないため falseとtrueどちらにも等値でない falseでない真偽値はtrueだが falseでない値はtrueとは限らない 「True, null」だから違和感が有って 「not false, null」なら無かったのでは >>333 リンク先のコード消えてるよ 同じ接続元・同じURLで開くと変更モードになるようだから 「新規コード」を押してから扱わないといけない \ ∩─ー、 ==== \/ ● 、_ `ヽ ====== / \( ● ● |つ | X_入__ノ ミ そんな餌で俺様が釣られクマ―― 、 (_/ ノ /⌒l /\___ノ゙_/ / ===== 〈 __ノ ==== \ \_ \ \___) \ ====== (´⌒ \ ___ \__ (´⌒;;(´⌒;; \___)___)(´;;⌒ (´⌒;; ズザザザ >>343 ちょまど神への信仰が不足しているか背教者ですね >>278 の本は何故か新品よりも高い中古がもう出ているw (値段のタイプミスか?) 購入者の確認不足や品切れ時にたまたま買われることを狙った有名な詐欺だよ >>347 確かに可愛いがムネ大き過ぎ。 D,EかせめてFカップなら信者になってた。 classのdelegateってinterfaceしか出来ないみたいだけど、 classやabstractのインスタンスでdelegateできない理由をご存知の方いらっしゃいますでしょうか。 可: class SubClass(instance: Interface) : Interface by instance 不可: class SubClass(instance: SuperClass) : SuperClass by instance もちろんSuperClassはopen指定してあります。 >>352 に答えられる人にそんな野暮なこと言う方はいないと思いますが念のため。 In Actionには「インターフェースを実装しいているなら〜」とさらっと書いていて クラスでdelegateできない理由は触れられていませんでした。 >>352-353 例えばこんな感じのKotlinコードをJavaへ変換してみればわかる interface Interface1 { ... } interface Interface2 { ... } class SubClass (impl1:Interface1, impl2:Interface2) : Interface1 by impl1, Interface2 by impl2 >>355 ありがとうございます。 interface Interface1 { ... } が open class Interface1 { ... } であったとしても、 class SubClass extends Interface1 implements Interface2 になるので、支障ないと思うのですが、どこか勘違いしていますでしょうか。 >>356 ごめん多重継承は関係無かったね 問題になるのはコンストラクタかな class SubClass extends SuperClass というJavaコードに相当するものに変換されるからには SuperClass のコンストラクタを呼ぶ必要があるけど、 でも SuperClass by instance によってインスタンスが別に渡されたらSuperClassの実体が二つになってしまう >>352 インターフェースでないと移譲が保証出来ないからでは インターフェースと違ってクラスの場合はそれが持つオーバーライド可能なメンバ全て移譲しても移譲になるとは限らない 例えば、あるライブラリがInterface, SuperClass, それらを引数に取る関数を提供しているとする Interfaceを受け取るならInterfaceとして扱うべき (内部の実装クラスへダウンキャスト出来ること等を前提とすべきでない)で、 SuperClassを受け取る場合も同様だが こちらはprivateメンバへのアクセスなども含まれていてそれは移譲出来ない >>352 abstractやclassじゃextendsになっちゃうじゃん したいのはimplementsじゃん だからOnly interfaces can be delegated toって言われちゃうんだよ >>357 の言いたかったこととは違うかもしれませんが、以下のように理解しました。 KotlinのdelegateはIn ActionではCollectionを引き合いに出しているが、 実際には、実装したクラスのコンストラクタがprivateで、 ヘルパークラスのファクトリメソッドを通じてしかインスタンスを生成できない ようなケースで力を発揮する。 コンストラクタがpublicでopenなclassやabstractの場合、素直に継承することを想定している。 In Actionの例も(共変とか反変とかを抜きにすれば)実はArrayListの継承で解決できる。 逆に、classでのdelegateを認めるとfinalなclassも継承できてしまい、 これを禁止するために規則を増やすことになる。 >>359 書き込んだ動機としては、多数のプロパティを持ったクラスを継承したい時に、 class SuperClass(val comp1: Comp1, val com2: Comp2, ...) class SubClass(instance: SuperClass) : SuperClass(instance.comp1, instance.comp2,...) とすると、かなり宣言が不格好になるので、 class SubClass(instance: SuperClass) : SuperClass by instance としたかったのです。 >>358 SuperClass内のSuperClassを引数に取る関数は、 SubClassにおいても引数としてSuperClassを渡せば正しく動作するので、 private(あるいはprotected)メンバへのアクセスがなくても、 実装可能でないかと思います。 ご指摘で理解できていない点があればご指摘いただければ幸いです。 皆様ありがとうございました。 interface InterfaceClazz{ val comp1:Any var comp2:Any fun method1() } class SuperClazz(override val comp1: Any, override var comp2: Any) :InterfaceClazz { override fun method1() { println("SuperClazz.method1 comp1:$comp1 comp2:$comp2") } } class SubClazz(instance:SuperClazz):InterfaceClazz by instance こういうのじゃだめなの? >>361 自分が作ったクラスの場合ならそうできることは考えましたが、 他人がinterfaceを定義せずに作ったクラスでやりたい場合どうすればいいんだろうという疑問でした。 Java, C# が、interface を作った理由は、 C++ のclass の、ひし形の形になる、ダイヤモンド継承を嫌ったから ほとんどの言語は、単一継承 + interface。 継承チェーンに、同じクラスが現れると困る 親クラス ← 子クラス1・2 ← 孫クラス 孫クラスが、子クラス1・2を多重継承すると、 両方の子クラス部分に、親クラスのメンバ変数を含んでしまう 孫クラスからすると、どちらの子クラス経由で、 親クラスのメンバ変数にアクセスすべきか、ややこしい だから多重継承用に、メンバ変数を持たず、メソッドだけを持つ、interface が作られた is-a・class・継承よりも、has-a・interface・委譲の方が、柔軟性があって好まれる 複数のinterfaceでメソッド名が被ってたらどうするの? パッケージ名とinterface名で指定するんじゃね >>364 実装はサブクラス側でやるんだからどうもなんねーだろ delegataion 使った >>355 みたいなので Interface1 と Interface2 に同じメソッドが定義されている場合にはエラーになるけど、 SubClass で override しろって IDE が言ってくるので、それすればエラーは消える delegatation 使わないのなら >>367 が言うようにサブクラスで実装するんだから関係無いね Delegataion ってなんだ・・・Delegation ね coroutine builderの例えばasyncの定義を見ると、 fun <T> async( context: CoroutineContext = DefaultDispatcher, start: CoroutineStart = CoroutineStart.DEFAULT, parent: Job? = null, block: suspend CoroutineScope.() -> T ): Deferred<T> (source) ってなってんですが、blockパラメータの型が関数型になっているのですが、 型の前にCoroutieScope.とかついてるのですが、これはなんなんでしょうか?? >>370 block内でのthisがその型のインスタンスになる 例 https://ideone.com/KsS26N >>371 ありがとうございます。 うーん。ややこしい。何のためにこんなのが必要なんだ・・ 呼び出される関数の方でもインスタンス(val a = A("aa"))を作って 関数を呼び出さないといけないってことですよね。 delegateってパフォーマンス悪かったりします? >>361 のような方法を試したら、目に見えて遅くなりました。 もっとも他にも色々いじった後だから、他が原因の可能性もありますが....。 エルビス式のエルビスって何ですか?プレスリーしか出てこないんですけど と思ってググったら本当にプレスリー由来だったのね、、 >>375 調べてみたら、delegateよりも前に速度低下はあったようでした。ありがとうございました。 ?: これのどこがプレスリーなんだよ?と思った時の脳内に浮かんでいたのはサタデーナイトフィーバーの人だったのは俺だけだろうな >>161 だけど Javaのリリースサイクルが6か月ごとになったので2018/3/20リリース予定 http://openjdk.java.net/projects/jdk/10/ ローカル変数の型推論きたー 後はGoogleさん早めにAndroidで使えるように。 後はkotlinを使ってみて自分的にうらやましのは ・Null safety ・1ファイルに複数のクラス書ける ・コルーチン ぐらいかな・・ 俺は ・val ・最後の引数のラムダを括弧の外に書けること ・「==」でnull考慮込みのequals()呼び出しにしてくれること とにかくJavaと同じことをするのに記述量が圧倒的に少なくて済むのが良いわ。 一つ一つはそれこそ数行程度の違いになるけど、チリが積もって最終的にかなり短くなって可読性が段違い Objective-Cを経験すれば大抵の言語は涙が出るほど読みやすい ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる