Kotlin 6
■ このスレッドは過去ログ倉庫に格納されています
JetBrainsが開発した期待の新言語、Androidの公式開発言語にしてサーバーサイドもなんでもいけるKotlinについて語りましょう ※前スレ Kotlin 5 https://mevius.5ch.net/test/read.cgi/tech/1544268581/ ていうかだな、VMのレベルでJavaとの互換性あるんだからJavaでできることはなんでもできるよな。 互換性というかJavaバイトコードそのままなわけだが。 何で誰もscalaのライブラリ移植してくれないんだ? >>358 JavaからScalaを呼び出せるはずだから、Kotlinからも呼び出せるのでは? bit演算子がand/orで、conditionalの方が&&/||って紛らわしいな。 >>360 伝統的に BASIC言語では、and, or が条件分岐(BOOL)用だったので、 混乱しそうですね。 単語と記号の混在が紛らわしいって話でしょ VB系がAndとAndAlsoで、C系が&と&&で一貫しているのに対して、Kotlinはandと&&の組み合わせを選んでて言われてみると少し変 andはメソッドで&&は演算子だから差別化したかったというなら理解できるが、andを演算子オーバーロードしなかったのは何でだろうな notはしてるのに VBではAndもAndAlsoも、条件分岐用(BOOL系)で、AndAlsoが、 C での&&相当なんですね。x And y も C のx && yに近いが、 xが偽の場合でもyを評価してしまうところが && と違う。 そこで && と同じ動作を行わせるために導入されたのが AndAlsoと。 Pythonは、kotlinとは反対だな。 and/orはいかにも文章的で、こっちの方がしっくりくる。 それに、&& や || は長さも & や | より長いので、少し長い and, or と対応し易い。 後やはり、伝統的なBASIC言語との互換性は重要だ。そっちを覚えている人は 世界では沢山入るはず。特にアメリカ。 >>365 誤:世界では沢山入るはず。特にアメリカ。 正:世界では沢山いるはず。特にアメリカ。 and, orは値によっては計算を評価しないというifの役目もしてるから ほかの演算子と一緒くたにするのは気分が悪かったのかもしれない とおもったけど&&使ってもandと評価される項目一緒だっけ Kotlinの言語開発者は、andとorは拡張関数で実装すればKotlinの文法の範囲内で文章的に書けると思ったのかも。 ただ、>>367 が指摘するように拡張関数のand, orは短絡評価がないから &&, ||とは同じ動作にならない上にパフォーマンスも若干落ちるという残念な仕様に。 将来的に短絡評価するアノテーションとかを作れば何とか出来ると思っているのかいないのか。 >>368 短絡評価しないから残念というものではなく副作用を考えて使い分けるものだよ だから多くの言語ではわざわざ2種類用意されてる 前段については同意だがやはりなぜ演算子オーバーロードしなかったのか疑問 ビット演算と論理演算の違いって>>360 が書いてるやろ ビット演算を短絡評価のない論理演算と捉えてるやつが多くてオシッコちびるわ ビット演算と論理演算の違いはC C# Javaとかでも同じっすよ 言語仕様を広げたくなかったんじゃね Kotlinのandとかは言語仕様に無くて単なる標準ライブラリの関数扱いだし >>369 演算子オーバーロードを許すと、Int, Boolean等以外のLocalDateTimeのようなプリミティブでない クラスにまでユーザーが論理演算(もしくはビット演算)を定義できてしまうから 好ましくないと思ったのかなと。 >>370 Booleanに限って言えばビット演算と論理演算は(短絡評価を除けば)等価なはず。 Booleanとand, orを組み合わせれば、(短絡評価の問題を除けば) &&, || が不要になる。 >>374 notやplusは演算子オーバーロードしてるのにandがしてないのが疑問だと言っているんだよ >>375 何を言っても推測にしかならないけど、一つは&&の短絡評価を演算子オーバーロードで再現できないからではと思う。 a && b が bがBooleanかどうかでbが評価されるかどうかが変わるということを避けたかったのではと。 もう一つは、>>372 の言うように言語仕様を最低限にしようとしたのではと思う。 Kotlinはシフト演算を見る限り、ビット演算しようとする人には優しくない気がする。 >>375 がandでオーバーロードしたかったのが&か&&かはっきりしないけど、少なくともどちらか一つは答えになっているかと。 「演算子オーバーロードしなかった」の意味がよくわからない &演算子が無いことの話なのか、オーバーロード出来るかどうかの話なのか 後者なら単なる関数なので普通に出来るけど class A(val s:String) { override fun toString() = s } infix fun A.and(o:A) = A("${this.s}∩${o.s}") fun main(args: Array<String>) = println( A("x") and A("y") ) 演算子がないことを、演算子オーバーロードしてないと言ってるんだろう https://github.com/Kotlin/KEEP/issues/142 中の人は演算子提供するのに乗り気じゃなさそうだけどそのうち追加されるんじゃないか shl/shrとかわかりにくいしand/orも他言語から来ると思考ノイズでしかない ビット演算するとき、|=、&=って激しく便利だし頻出だと思うんだけどなぁ。 そもそも複数のbooleanで扱うべきフラグをビット演算で1つにしてるAPI設計が良くない説 >>380 ハードウェアがそうなってるのだから仕方なかろう。 いっぺんに書き換えないと挙動が変わってしまう javaラーがコトリンに乗り換える勉強するのにどれくらい移行期間かかります? 超天才でスーパーな人なら入門書パラパラめくって眺めて30分ぐらいかな java -> kotlin変換しますか? Y?/N? Y -> 数秒まて それだと !! がたくさん残るしそもそもビルド通らない そっから手直しすればいいんじゃない?? 無駄が多いし効率も悪いけど… あれ?forループで変数インクリメントするようなのできねーじゃん。なに?while使ってやれっての?えー! ってなってから、なーんだ (a..b).forEach { } でやりゃあいいんじゃん。 と、気づくまでに3日以上掛かった。 ていうか for (n in a..b) でもいいのだが、a..b が Range になっててあとはコンパイラが自動でうまいことやってくれる事に気づかなかった。 ひとまず小一時間感覚で書いてみるのは良いとしても 言語リファレンスを一通り流し読みする時間をどこかで確保しないとな https://kotlinlang.org/docs/reference/idioms.html !!ってダメなのか? むしろ入れて解決してるんだが…w なぜどうしてもそこに必要なのかを説明できない!!は書いてはならない あとあと絶対にそこでコード的にまたは仕様的にバグるから、むしろ遠回りになる null許容変数がnullになるかもしれないから!!なんじゃないの? そういう認識なんだが val a = ThreadLocal<String>().get() val b:String = a //暗黙の a!! >>400 動作の説明としては全くその通り しかしそれをコードに適用するデメリットが大きいので全世界中からやめと毛と言われている >>403 nullになるかも?なだけで実行順を追っていくとならないことが多いからそのままにしている 必要なら対策するけど、ほとんどの場合は実行タイミングに何か値が入ってる 変に怖れて潔癖にならない方がいい !! は、絶対に、null にならない場合だけに使うべし! notnull 強制キャストと同じ 例外が発生するから!!が良くないと考えているならそれはnull安全を履き違えている 重要なのは区別することで、どう処理するかは要件次第 処理のタイミングで非nullであるべき変数なら ガード節、requireNotNull、!! などによって早期にスマートキャストすべき そのような箇所で不用意にセーフコール(?.)を使うことはいわゆるエラーの隠蔽に繋がる nullが正常系の内ならもちろんセーフコールなりエルビスなりで問題無い !!はforce unwrapと呼ぶべし!! !!演算子に名前を付けない言語は滅ぶべし!! >>408 Kotlin公式では not-null assertion operator とある Swiftと合わせた方が分かりやすいとは思うけどな 例えば画像Aを表示する座標x,y 初期値を画面外の-500,-500にしておけば!!は消せるけど 画面外に表示ってリソースの無駄 これを良しとするやつは複数の画像を画面外に常に表示している 逆にメモリ足らなくなって落ちない? 使わない場合はnullでよくね? 読込みに時間かかるなら初期値設定するのもありだけど あくまで重い画像を複数使用する例なんだけどnullを悪としてとらえず利用しようよ 上記の理由により、!!潔癖症はただ邪魔なだけ !!を使わなくても安全に実装できるのにあえて!!を使うのは頭が悪いですと言っているようなもの ファイルヘッダとかにマジック定数あるが、これを表現するには val hoge = arrayOf('a','1').map { it.toByte() }.toByteArray() みたいな悲しいことしないといけないのでしょうか? それとkotlinで一般的なバイトバッファを表現するにはByteArrayつかっておけば間違いなないでしょうか? 今はJVM環境で使ってますが、一応コード書くときに、特定のプラットホームに依存しないように書けるとこは書こうと思います ちょっとつっぱしてByteArrayじゃなくてexperiment なUByteArrayを使おうと思いますが >>411 なぜ使うべきでないのかを説明出来ない限り、議論の出発点にも立っていない 例えば俺は>>407 で書いた順の通りガード節、requireNotNullの方が より明示的かつメッセージ付加可能でなので!!より優先すべきと考えるが 本質的には大差無い NullObjectパターンは有用ではあるが セーフコールがあるKotlinでは必ずしも必要としない そのようなケースはnullが正常系の内であるのと同義 >>410 使わない場合はnull、っていうケースは文字通りガード節や?.を使って nullならなにもしない場合、と同義なのでは !!を使うべき例としてはピンとこない !!を使っている関数は引数つまり関数の仕様としては一見null許容型だけど、実装としてはnullを拒絶する不整合がある 何らかの事情で回避が難しいときの苦肉の策で、多用するのは作りが悪いように思う あとは関数内で既に非nullであることが保証されてるパスの中にいる場合の簡略化で使うか でもこれを多用するようなら関数が長すぎるという問題を暗に抱えていたり 安全や可読性よりも手抜きを選ぶ悪癖の疑いを感じる !! null即エラー演算子。 force unwrapでは全く本質を言ってない。 >>414 型安全でないnullを使うこと自体が問題。 !!も、使う前に型安全なnullobjectを検討すべき。 checkNotNull(nullable) { "説明" } がいいんだろうけど、!! で楽したくなる時がある >>412 byteArrayOf が使いたいって言ってる? >>410 もし遅延初期化、lateinit が使えるなら、その方がよい java のライブラリの @Nullable とか、json で条件によって null / not null が切り替わるプロパティとか >>427 nullableな値を返す外部の関数について、文脈上nullが返らないことが保証できる場合にまで null対応を書くのは、可読性やパフォーマンスの上で無駄が多いからだと思う。 特にJava(あるいはJavascriptやnative)由来の関数とか。 >>429 誤解されそうなので補足。 1行目の「外部」っていうのは3行目のKotlin外という意味ではなくて、 標準ライブラリを含めて他人が作ったライブラリという意味です。 そのkotlinの存在意義ぶち壊す特異性からしても、どーしても仕方なく使うものであるのだけど エラー消すおまじないみたいなノリで初心者から中級者が使うので戒められている次第 あと、感染するんだコレ >>426 >>431 requireNotNullは? 1.3.60出てたから久しぶりにkotlin native試してみたらhello,worldのコンパイル時間が更に伸びてた! 10秒→16秒! 何か早くする方法ないの? 実行タイミングが来るまで置いておくだけの関数の中で使う変数は、その関数を実行する前までnullでいいよな? そういう理由で!!のままにしてるんだけど!!潔癖以外の意見が聞きたい、ロジカルな理由を その会社の規約なら!!使わないけど 使っていけないならそもそもビルド通らんだろ >>435 型安全が破綻するのでnullobject定義して使っとけ。 >>433 所詮はオモチャなんだからどうでもいいでしょ JetBrainsとしてもまだコンパイル時間の最適化なんか気にする段階じゃないだろうし 状況が限定されるが、あるクラスがnull相当の状態をとりうるメンバ変数を持っていて その値がnullのときに呼んだらバグとして例外を出したいメソッドがあるときは !!を使ってもいいかなと思う requireNonNullのほうが可読性と保守性でベターだけど本質的には大差ない 残念な!!の使い方ではないんですよと表明している程度(それが重要でもあるわけだが) NullObjectパターンは必ずしも良い置き換えにはならない NullObjectかどうか忘れず判定してIllegalStateExcptionを投げなければならない状況になるくらいなら nullチェックを言語仕様で強制されるほうが手が掛からず安全性も高い 上でも言われていたが例外も何も出ずにバグがしれっと埋もれるほうが危険 require と check の使い分けちゃんとしとけよ >>438 オモチャだから発売日が気になっちゃう精神やん >>435 ものによる。初期化しないとか by lazy にするとか他の方法があるならそちらを使う方が良いかも知れない。 nullのまま素通りさせたくない場合は !!でなくcheckNotNullやrequireNonNullを使えばOK? このコードの3つ目のように https://paiza.io/projects/Ao4mGnYxwoWEuMNRtj_gkg >>438 nullには型チェックが働かないことを忘れちゃいかん。 nullobjectじゃなくてnullがきたときは型チェックでエラーにできるんだから、nullobjectを使ったほうがいい。 !!潔癖症でもいい 変更方法さえ教えて頂けるなら それに従い変更します Kotlinプログラマーは未だにforce unwrappingの使いどころを知らない NullObjectのメリットデメリットも知らない ということはよ〜くわかった >>444 >432と>>442 についても意見が欲しい >>448 nullobjectのデメリットって、null汚染されたクラスの再利用が面倒なことくらいじゃない? 他になんかある? NullObjectのデメリット? 「オナニーとしては気持ちいいが、実際の開発において便利なシーンがほとんどない」 これに尽きる >>451 オナニーとして気持ちいいなら誰でも使うだろ。 そんなこともわからない無能かぁ…… あるデータが有限の数値をとる場合と 値なしの特殊な状態をとる場合があるとする その厄介さってのは多くの場合、処理の場合分けが必要ってところにある ヒトがそういう分岐を書き忘れがちなのはご存じの通り その結果もあって多くのプログラマはNPE恐怖症になったが、NPEを回避することが目的になっても意味がない NullObjectの多態性やアルゴリズムの妙で分岐を潰せるならベスト だがそうでない場合、むしろ分岐を書き忘れたとき、下手なNullObjectはフェイルファストのメリットを失うことがある nullセーフな言語におけるNullable型の素晴らしい点は そのままではメソッドを呼び出すことができず 特殊値に対し場合分けの判断が必要ではないかとヒトに思い出させてくれること 不適切な!!はこれを台無しにする 不適切なNullObjectも同じで、より厄介なバグ隠蔽をもたらす >>454 requireNotNullやcheckNotNullも同じく台無しにする? それともこっちは良い? !!のほうが2文字だし、ここでヌルポが上がるかもと分かるので好き ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる