Kotlin 6

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2019/06/22(土) 15:59:57.23ID:zj+KJbMh
JetBrainsが開発した期待の新言語、Androidの公式開発言語にしてサーバーサイドもなんでもいけるKotlinについて語りましょう

※前スレ
Kotlin 5
https://mevius.5ch.net/test/read.cgi/tech/1544268581/
2019/11/16(土) 20:26:59.99ID:t3f2p1SX
1年働く
2019/11/16(土) 20:43:38.98ID:C0dcrxXu
>>383
君の全角半角のセンスからするとだな
386デフォルトの名無しさん
垢版 |
2019/11/16(土) 22:11:24.92ID:gv6Xc8ej
超天才でスーパーな人なら入門書パラパラめくって眺めて30分ぐらいかな
387デフォルトの名無しさん
垢版 |
2019/11/16(土) 22:13:58.74ID:gv6Xc8ej
1時間後にはもっと凄い新言語に閃いて作りはじめる
2019/11/16(土) 23:33:33.74ID:uUrUP5Ld
java -> kotlin変換しますか?
Y?/N?

Y -> 数秒まて
2019/11/17(日) 00:14:20.35ID:JQ6H4Wt1
それだと !! がたくさん残るしそもそもビルド通らない
2019/11/17(日) 09:48:27.71ID:fq5Zb79J
そっから手直しすればいいんじゃない??
無駄が多いし効率も悪いけど…
2019/11/17(日) 11:45:54.92ID:os2yIBUt
3日で慣れる
392デフォルトの名無しさん
垢版 |
2019/11/17(日) 17:31:59.24ID:8gWobnsK
あれ?forループで変数インクリメントするようなのできねーじゃん。なに?while使ってやれっての?えー!

ってなってから、なーんだ (a..b).forEach { } でやりゃあいいんじゃん。
と、気づくまでに3日以上掛かった。
393デフォルトの名無しさん
垢版 |
2019/11/17(日) 17:34:56.22ID:8gWobnsK
ていうか for (n in a..b) でもいいのだが、a..b が Range になっててあとはコンパイラが自動でうまいことやってくれる事に気づかなかった。
2019/11/17(日) 23:38:24.23ID:moRzMRqx
ひとまず小一時間感覚で書いてみるのは良いとしても
言語リファレンスを一通り流し読みする時間をどこかで確保しないとな
https://kotlinlang.org/docs/reference/idioms.html
2019/11/19(火) 06:21:31.09ID:bEq52YpT
!!ってダメなのか?
むしろ入れて解決してるんだが…w
2019/11/19(火) 09:50:11.74ID:LM0oqXyj
!!は全部消さないとダメ
397デフォルトの名無しさん
垢版 |
2019/11/19(火) 09:55:32.18ID:c65LTQ+s
>>395
ダメじゃないけど沢山あると嫌な感じ
2019/11/19(火) 10:47:58.28ID:DczGG2/f
Kotlin 1.3.60 リリース
https://blog.jetbrains.com/kotlin/2019/11/kotlin-1-3-60-released/
2019/11/19(火) 14:30:37.08ID:trU3CZAC
なぜどうしてもそこに必要なのかを説明できない!!は書いてはならない
あとあと絶対にそこでコード的にまたは仕様的にバグるから、むしろ遠回りになる
2019/11/19(火) 16:25:17.02ID:bEq52YpT
null許容変数がnullになるかもしれないから!!なんじゃないの?
そういう認識なんだが
2019/11/19(火) 16:29:22.93ID:DczGG2/f
val a = ThreadLocal<String>().get()
val b:String = a //暗黙の a!!
2019/11/19(火) 19:32:30.25ID:OgKqA1p2
!!は全部消すべき
2019/11/19(火) 19:39:12.55ID:bMvJvF/Q
>>400
動作の説明としては全くその通り
しかしそれをコードに適用するデメリットが大きいので全世界中からやめと毛と言われている
404デフォルトの名無しさん
垢版 |
2019/11/19(火) 21:21:13.73ID:c65LTQ+s
2019/11/19(火) 23:23:22.22ID:bEq52YpT
>>403
nullになるかも?なだけで実行順を追っていくとならないことが多いからそのままにしている
必要なら対策するけど、ほとんどの場合は実行タイミングに何か値が入ってる
変に怖れて潔癖にならない方がいい
2019/11/20(水) 00:18:44.73ID:Cb5VPrea
!! は、絶対に、null にならない場合だけに使うべし!
notnull

強制キャストと同じ
2019/11/20(水) 00:47:14.79ID:ENHG5n4o
例外が発生するから!!が良くないと考えているならそれはnull安全を履き違えている
重要なのは区別することで、どう処理するかは要件次第

処理のタイミングで非nullであるべき変数なら
ガード節、requireNotNull、!! などによって早期にスマートキャストすべき
そのような箇所で不用意にセーフコール(?.)を使うことはいわゆるエラーの隠蔽に繋がる

nullが正常系の内ならもちろんセーフコールなりエルビスなりで問題無い
2019/11/20(水) 00:51:02.81ID:I+/vz2hc
!!はforce unwrapと呼ぶべし!!
!!演算子に名前を付けない言語は滅ぶべし!!
2019/11/20(水) 00:53:35.65ID:ENHG5n4o
>>408
Kotlin公式では not-null assertion operator とある
Swiftと合わせた方が分かりやすいとは思うけどな
2019/11/20(水) 01:40:06.34ID:We9TyGj3
例えば画像Aを表示する座標x,y
初期値を画面外の-500,-500にしておけば!!は消せるけど
画面外に表示ってリソースの無駄
これを良しとするやつは複数の画像を画面外に常に表示している
逆にメモリ足らなくなって落ちない?
使わない場合はnullでよくね?
読込みに時間かかるなら初期値設定するのもありだけど
あくまで重い画像を複数使用する例なんだけどnullを悪としてとらえず利用しようよ
上記の理由により、!!潔癖症はただ邪魔なだけ
2019/11/20(水) 02:09:26.97ID:6LF6wg+P
!!を使わなくても安全に実装できるのにあえて!!を使うのは頭が悪いですと言っているようなもの
2019/11/20(水) 07:14:57.99ID:U5Gi9XNc
ファイルヘッダとかにマジック定数あるが、これを表現するには
val hoge = arrayOf('a','1').map { it.toByte() }.toByteArray()

みたいな悲しいことしないといけないのでしょうか?

それとkotlinで一般的なバイトバッファを表現するにはByteArrayつかっておけば間違いなないでしょうか?
2019/11/20(水) 07:18:15.00ID:U5Gi9XNc
今はJVM環境で使ってますが、一応コード書くときに、特定のプラットホームに依存しないように書けるとこは書こうと思います

ちょっとつっぱしてByteArrayじゃなくてexperiment なUByteArrayを使おうと思いますが
2019/11/20(水) 07:47:32.01ID:ENHG5n4o
>>411
なぜ使うべきでないのかを説明出来ない限り、議論の出発点にも立っていない

例えば俺は>>407で書いた順の通りガード節、requireNotNullの方が
より明示的かつメッセージ付加可能でなので!!より優先すべきと考えるが
本質的には大差無い

NullObjectパターンは有用ではあるが
セーフコールがあるKotlinでは必ずしも必要としない
そのようなケースはnullが正常系の内であるのと同義
2019/11/20(水) 09:35:14.21ID:kKZK+bE1
>>410
使わない場合はnull、っていうケースは文字通りガード節や?.を使って
nullならなにもしない場合、と同義なのでは
!!を使うべき例としてはピンとこない

!!を使っている関数は引数つまり関数の仕様としては一見null許容型だけど、実装としてはnullを拒絶する不整合がある
何らかの事情で回避が難しいときの苦肉の策で、多用するのは作りが悪いように思う

あとは関数内で既に非nullであることが保証されてるパスの中にいる場合の簡略化で使うか
でもこれを多用するようなら関数が長すぎるという問題を暗に抱えていたり
安全や可読性よりも手抜きを選ぶ悪癖の疑いを感じる
416デフォルトの名無しさん
垢版 |
2019/11/20(水) 11:41:13.79ID:NJaF4OnZ
!! null即エラー演算子。
force unwrapでは全く本質を言ってない。
2019/11/20(水) 12:48:32.17ID:RdkdotSG
>>414
型安全でないnullを使うこと自体が問題。
!!も、使う前に型安全なnullobjectを検討すべき。
2019/11/20(水) 14:43:02.05ID:6LF6wg+P
!!を使うやつとは一緒に仕事したくない
2019/11/20(水) 15:16:56.32ID:zV5Z2B9p
なんだと!!
2019/11/20(水) 15:29:37.98ID:Y9hbFaQz
>>419
ちょっとワロタw
421デフォルトの名無しさん
垢版 |
2019/11/20(水) 17:12:40.65ID:gQNT2Wxf
val なんだと: Int? = null
2019/11/20(水) 22:37:14.64ID:F7b4EQq2
checkNotNull(nullable) { "説明" } がいいんだろうけど、!! で楽したくなる時がある

>>412
byteArrayOf が使いたいって言ってる?
2019/11/20(水) 23:09:14.16ID:V5o6b7gh
絶対nullにならないなら型変えるべき
2019/11/20(水) 23:19:54.39ID:Cb5VPrea
>>410
もし遅延初期化、lateinit が使えるなら、その方がよい
2019/11/21(木) 00:03:38.40ID:OWTu/Eih
java のライブラリの @Nullable とか、json で条件によって null / not null が切り替わるプロパティとか
2019/11/21(木) 02:18:34.58ID:TLoSEVN8
!!使うやつは馬鹿でFA
2019/11/21(木) 03:55:49.74ID:Bt7t64ET
ならなんであるんだろう
428デフォルトの名無しさん
垢版 |
2019/11/21(木) 04:20:54.23ID:UJdhtJJC
あたたたたたたたひでぶ!!
2019/11/21(木) 06:28:21.69ID:87sZA2Me
>>427
nullableな値を返す外部の関数について、文脈上nullが返らないことが保証できる場合にまで
null対応を書くのは、可読性やパフォーマンスの上で無駄が多いからだと思う。
特にJava(あるいはJavascriptやnative)由来の関数とか。
2019/11/21(木) 06:34:18.07ID:87sZA2Me
>>429
誤解されそうなので補足。
1行目の「外部」っていうのは3行目のKotlin外という意味ではなくて、
標準ライブラリを含めて他人が作ったライブラリという意味です。
2019/11/21(木) 06:56:28.51ID:SWfOk2xI
そのkotlinの存在意義ぶち壊す特異性からしても、どーしても仕方なく使うものであるのだけど
エラー消すおまじないみたいなノリで初心者から中級者が使うので戒められている次第
あと、感染するんだコレ
2019/11/21(木) 07:43:43.53ID:rXpcOZh/
>>426 >>431
requireNotNullは?
2019/11/21(木) 08:03:18.32ID:tRt1kz+E
1.3.60出てたから久しぶりにkotlin native試してみたらhello,worldのコンパイル時間が更に伸びてた!
10秒→16秒!
何か早くする方法ないの?
2019/11/21(木) 08:04:59.80ID:SWfOk2xI
>>432
値チェックに使う字面だからいいのでは
2019/11/21(木) 08:06:53.77ID:Bt7t64ET
実行タイミングが来るまで置いておくだけの関数の中で使う変数は、その関数を実行する前までnullでいいよな?
そういう理由で!!のままにしてるんだけど!!潔癖以外の意見が聞きたい、ロジカルな理由を
その会社の規約なら!!使わないけど
使っていけないならそもそもビルド通らんだろ
2019/11/21(木) 08:38:35.83ID:9TFt1oIy
>>435
型安全が破綻するのでnullobject定義して使っとけ。
2019/11/21(木) 08:53:15.49ID:0YdMrNda
>>433
所詮はオモチャなんだからどうでもいいでしょ
JetBrainsとしてもまだコンパイル時間の最適化なんか気にする段階じゃないだろうし
2019/11/21(木) 08:54:35.85ID:Vn+a4ljF
状況が限定されるが、あるクラスがnull相当の状態をとりうるメンバ変数を持っていて
その値がnullのときに呼んだらバグとして例外を出したいメソッドがあるときは
!!を使ってもいいかなと思う

requireNonNullのほうが可読性と保守性でベターだけど本質的には大差ない
残念な!!の使い方ではないんですよと表明している程度(それが重要でもあるわけだが)

NullObjectパターンは必ずしも良い置き換えにはならない
NullObjectかどうか忘れず判定してIllegalStateExcptionを投げなければならない状況になるくらいなら
nullチェックを言語仕様で強制されるほうが手が掛からず安全性も高い
上でも言われていたが例外も何も出ずにバグがしれっと埋もれるほうが危険
2019/11/21(木) 09:05:08.85ID:OWTu/Eih
require と check の使い分けちゃんとしとけよ
2019/11/21(木) 10:47:03.33ID:iVxfes4g
>>438
オモチャだから発売日が気になっちゃう精神やん
441デフォルトの名無しさん
垢版 |
2019/11/21(木) 10:50:30.22ID:PQRrRahX
>>435
ものによる。初期化しないとか by lazy にするとか他の方法があるならそちらを使う方が良いかも知れない。
2019/11/21(木) 11:30:32.58ID:rXpcOZh/
nullのまま素通りさせたくない場合は
!!でなくcheckNotNullやrequireNonNullを使えばOK?

このコードの3つ目のように
https://paiza.io/projects/Ao4mGnYxwoWEuMNRtj_gkg
2019/11/21(木) 13:52:56.76ID:fDxQUKzN
香ばしくなってまいりました
2019/11/21(木) 14:50:53.35ID:TLoSEVN8
!!を使うやつを絶対に許してはいけない
2019/11/21(木) 15:08:48.23ID:t44F/vpr
明日の朝刊載ったゾ テメー!!
2019/11/21(木) 15:30:07.46ID:9TFt1oIy
>>438
nullには型チェックが働かないことを忘れちゃいかん。

nullobjectじゃなくてnullがきたときは型チェックでエラーにできるんだから、nullobjectを使ったほうがいい。
447デフォルトの名無しさん
垢版 |
2019/11/21(木) 16:27:17.17ID:Bt7t64ET
!!潔癖症でもいい
変更方法さえ教えて頂けるなら
それに従い変更します
2019/11/21(木) 16:37:36.16ID:GN1h9TxM
Kotlinプログラマーは未だにforce unwrappingの使いどころを知らない
NullObjectのメリットデメリットも知らない
ということはよ〜くわかった
2019/11/21(木) 18:30:46.10ID:rXpcOZh/
>>444
>432と>>442についても意見が欲しい
2019/11/21(木) 18:59:57.13ID:ikLBAUPH
>>448
nullobjectのデメリットって、null汚染されたクラスの再利用が面倒なことくらいじゃない?
他になんかある?
2019/11/21(木) 19:03:08.50ID:Bs6+HN1r
NullObjectのデメリット?
「オナニーとしては気持ちいいが、実際の開発において便利なシーンがほとんどない」
これに尽きる
2019/11/21(木) 20:29:13.59ID:ikLBAUPH
>>451
オナニーとして気持ちいいなら誰でも使うだろ。
そんなこともわからない無能かぁ……
2019/11/21(木) 22:54:14.17ID:Vn+a4ljF
あるデータが有限の数値をとる場合と
値なしの特殊な状態をとる場合があるとする
その厄介さってのは多くの場合、処理の場合分けが必要ってところにある
ヒトがそういう分岐を書き忘れがちなのはご存じの通り
その結果もあって多くのプログラマはNPE恐怖症になったが、NPEを回避することが目的になっても意味がない
NullObjectの多態性やアルゴリズムの妙で分岐を潰せるならベスト
だがそうでない場合、むしろ分岐を書き忘れたとき、下手なNullObjectはフェイルファストのメリットを失うことがある
2019/11/22(金) 08:14:50.32ID:GTCFu0T7
nullセーフな言語におけるNullable型の素晴らしい点は
そのままではメソッドを呼び出すことができず
特殊値に対し場合分けの判断が必要ではないかとヒトに思い出させてくれること
不適切な!!はこれを台無しにする
不適切なNullObjectも同じで、より厄介なバグ隠蔽をもたらす
2019/11/22(金) 09:18:52.84ID:hf/6/1tn
>>454
requireNotNullやcheckNotNullも同じく台無しにする?
それともこっちは良い?
2019/11/22(金) 10:51:25.32ID:+tlCvVPc
!!のほうが2文字だし、ここでヌルポが上がるかもと分かるので好き
2019/11/22(金) 11:13:57.45ID:hf/6/1tn
念のため書いておくとKotlin標準ライブラリの関数のことね
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/check-not-null.html
2019/11/22(金) 15:35:14.32ID:GTCFu0T7
>>455
何を使うにしても状況に適したものを使えば問題ないと思うよ
2019/11/24(日) 06:37:41.88ID:wyfl3vqB
>>450
NullObjectはどのような場合でも正しく機能するNullObjectを定義できるなら優れているが、「どのような場合でも」を満たすのは難しい。
null発生の状況が複数ある場合は「どのような場合でも」というい条件を満たすNullObjectが定義可能である保証もない。
最初は条件を満たしていても、プログラムを修正していくうちに条件を満たせない場合が出てくる可能性もある。
しかも「気づかないうちに」そうなっている可能性がありたちが悪い。
条件を満たせない場所だけ分岐させるのは、NullObjectがnullチェック分岐消去を目的にしている
ことを考えると本末転倒な解決策。
2019/11/24(日) 12:53:04.20ID:gnIUHiL6
APIレスポンスとかデータ定義はNULLじゃない扱いしておいてビルドエラーもでないけど、
実際に動作させるとNULLが来てクラッシュするとかあるな
461デフォルトの名無しさん
垢版 |
2019/11/25(月) 11:44:00.50ID:8LK1eAYw
すごーく簡略化すれば、
private hoge: Hoge? = null
public Hoge apiX() {
if (hoge == null) hoge = Hoge() //
return hoge!! // ここでnullはあり得ないよと「宣言」
}
実際にHoge()のところは、さらにJavaの他のAPI呼び出しだったりするとしても、
とにかくnullでないことさえはっきりしているならばなんでもいい。
要するにこの場合は、apiXがnullを消費する責任を持つってことだ。
持たないなら、nullableのまま返す(つまりAPIとしてはnullも正常系だと言っている)。
そんだけのことじゃないかな。
2019/11/25(月) 12:58:08.39ID:Yrf4rnTG
>>459
nullobjectは「賢いnull」なんだから、null的な使い方してもいいだろ。
型安全なnullとして受け取ってnull分岐してもいいしな。

あと、null発生の状況が複数あるなら、それぞれ別のnullobjectにしていいんじゃない?。
2019/11/25(月) 16:14:54.66ID:c3GBXbYR
Javaではnullobjectを賢いnullとするのは正しいと思う

でもnull許容/非許容を型で区別出来るようになったKotlinでは
nullobjectはその利点を無くしてしまう

実装持ちobjectとnullobjectを区別する必要が無い場合は何も問題無いけど
もし「nullobjectかどうか」を判定する必要がある場合は
賢いどころか逆になると思う
2019/11/25(月) 17:15:40.69ID:1vTuETYq
NullObjectは"Tell, Don't Ask"なクラス設計ではうまく機能するんだけど、
関数型チックになAskだらけのコードだと使い物にならんね
465デフォルトの名無しさん
垢版 |
2019/11/25(月) 17:22:39.99ID:6yLunbOP
>もし「nullobjectかどうか」を判定する必要がある場合は
これはないだろ。動機そのものだから。
2019/11/25(月) 18:23:52.73ID:c3GBXbYR
>>465
それなら良いけど、ケースによらずnullの代わりに使うみたいな話の流れだったから
ログインユーザーとかも無効ユーザーオブジェクトになるのかなと
2019/11/25(月) 18:24:22.70ID:OXWkeipl
nullの場合の動作を
呼び出す側が決めるのか呼び出される側が決めるのか
どちらが適切なのかを考えるといい

呼び出される側が100%決め打ちできるユースケースならNullObjectは有効
呼び出し側でハンドリングしたくなったら邪魔
2019/11/25(月) 18:27:30.40ID:WgtQU+bP
java脳からkotlin脳へアプデが必要だけど
私の脳はnull
469デフォルトの名無しさん
垢版 |
2019/11/25(月) 18:49:15.70ID:6yLunbOP
Null Objectは単なる先送りで、ある意味!!が目指す方向とは真逆。
エラーが起きないから落ちることはないだろうけど、
使う側はエラーなのか無視されているのかわかりにくくなる。
2019/11/25(月) 19:00:53.76ID:Yrf4rnTG
>>468
>呼び出し側でハンドリングしたくなったら邪魔

型無しのnull使うよりマシだろ。
許容するととんでもないところから紛れ込むnullの方がよっぽど邪魔。
2019/11/25(月) 19:04:09.34ID:OXWkeipl
>>470
Nullableって知ってる?
2019/11/26(火) 08:06:30.50ID:cEMWujE4
>>471
nullableでnon-nullにできたっけ?
2019/11/26(火) 09:17:18.40ID:i6eVGflj
>>472
nullが正常系である場所ではnullabeを使い、nullが紛れ込んだらバグになる場所では非nullを使うって話がもう出てる
適切にゾーニングできているなら紛れ込むことをそう恐れる必要がない
nullという特殊値に対して意識が必要な場所はnullabeという型で言語仕様レベルで明確化でき区別できるからメリットがあり、型無しのnullというほど不便なものでもない
2019/11/26(火) 09:21:30.92ID:i6eVGflj
>>465
それがないならNullObjectがいいと思うよ
そこを否定している人はいないはず
ただ多くの人は経験上避けがたいと思ってるから意見が合わないんだろうね
解放閉鎖原則と単一責任原則とで作ってくと最初の動機だけではなかなか完結しない
全部ビジターパターンでとことんNullObject-ableな型にお伺いをたてるように作れば完璧にできるだろうけど、そこまで作り込むコストを考えたら適材適所でnullableを使い分けるのが現実解ってのが落としどころだと思う
Kotlinが選び提供している価値はnullセーフであってnullフリーではないし
2019/11/26(火) 10:05:06.19ID:XO/gVUyI
NullObjectって非同期呼び出しとかどうすんの
OOの原理主義的にはコールバックの呼び出しもしないのが正しいんだろうけど、
最近は前後で文脈が繋がってて、コールバックが呼ばれないままだとまともに動かないケースがほとんどだよね
かといってコールバックしようにも引数に何渡せばいいのかとか色々無理がある
2019/11/27(水) 12:20:06.50ID:OjEIAAu4
>>473
nullを使っても問題は限定的だと思うけど、あえてnullを使うメリットはあるのかしらん?
実装上の手間が省ける、くらいしかないと思うけど。
2019/11/27(水) 12:55:51.34ID:4s/5SlmV
>>476
>>438,453-454あたりを見てくれ
2019/12/06(金) 11:58:04.47ID:tlCdS/Zs
なぜKotlin/Nativeのメモリモデルが成り立たないか
https://itnext.io/why-the-kotlin-native-memory-model-cannot-hold-ae1631d80cf6
479デフォルトの名無しさん
垢版 |
2019/12/06(金) 14:42:47.13ID:08yg4gJX
三行に要約すると?
2019/12/06(金) 15:14:59.67ID:tlCdS/Zs
>>479
freezeによる制限とAPIはKotlin/Nativeのみ
そのせいでマルチプラットフォーム機能がお通夜状態
だから考え直せ
2019/12/06(金) 16:40:22.09ID:e8Nbwz4h
> This is the work of “top-level objects are frozen by default” and “a frozen datum cannot be mutated”.
Kotlin native試したことないけどこれ糞過ぎやろ
既存の(JVM向けに書かれた)コードがほぼ例外なく実行時にクラッシュすることになるやんけ
こんな互換性の欠片もないもん作るんやったらもう別言語でええやろ
482デフォルトの名無しさん
垢版 |
2019/12/06(金) 22:26:57.61ID:7KbOmiy4
kotlinてクラス変数に型推論使えるの?
Javaで無名クラスに利用できたらいいのにと思ったことがある

class Hello {
public var xyz = new Object (){ int x; int y; int z; };
void setX(int value){ xyz.x = value; }
}
2019/12/06(金) 23:00:45.17ID:tlCdS/Zs
>>482
private varでもいいなら使える
https://paiza.io/projects/qjWZT-Uy91UelIcTFqoKIA
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況