質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

2回答

3831閲覧

数値リテラルと型変換?について

mosa

総合スコア218

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

2クリップ

投稿2017/09/25 07:00

いつもありがとうございます。
Kotlin の数値リテラルと型変換?についての質問です。

###ソースコード

Kotlin

1val a = 3 // OK. 型推論されInt型の数値みなされる。 2val l:Long = 3 // OK. Long型の3とみなしてくれる。 3L でもよい。 3val i:Int = 3 // OK. 4val s:Short = 3 // OK Short型の3とみなしてくれる。 Short型の数値リテラルがない。 5val b:Byte = 3 // OK. Byte型の3とみなしてくれる。 Byte型の数値リテラルがない。 6val d:Double = 3 // NG. Double型の3.0とはみなしてくれない。 3.0 としなければならない。 7val f:Float = 3.0 // NG. Float型の3.0とはみなしてくれない。 3.0f or 3.0F としなければならない。 8 9val l1:Long = 3l // NG. 10val l2:Long = 3L // OK. 11val f1:Float = 3.0f // OK. 12val f2:Float = 3.0F // OK. 13

###質問

質問1.
Long・Floatの数値リテラル指定方法はあるのに、Short・Byte・Doubleにないのはなぜ?
→Long, Short, Byte, Double, Float 全てに数値リテラル指定があったほうが統一感があると思います。(2L, 2S, 2B, 3.0D, 2.0F のように)

質問2.
Long・Short・Byteはリテラル代入時に自動的に型変換をしてくれるのにDouble・Floatではしてくれないのはなぜ?
→整数値と浮動小数値の違いはわかりますが、変数の型に応じて自動的に型変換するという意味では機械的に 3 を Double の 3.0 とみなしたほうが統一感があるのではないかと思います。
→少なくともFloat型に関してはShort・Byteに合わせて3.0でも可としないと統一感がない気がします。

質問3.
Float は 3.0f 3.0F と両方の表記が許されるのに、Long は 3lという表記が許されないのはなぜ?
→小文字の「エル」が数字の「いち」と見分けづらいから?


合理的な理由があってのものだと思うのですが、なんだか統一感が無い気がして質問させていただきました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

質問2については
https://kotlinlang.org/docs/reference/basic-types.html
公式ドキュメントには、数値についてはByteからIntのような小さい型から大きい型への暗黙的な変換は行われない、と書かれています。
数値リテラルについては大きい型から小さい型への暗黙的な変換が許されているのでしょう。
一度変数に入れた場合は型にしばられるため異なる型には暗黙的に変換されません。
DoubleとFloatはそれぞれリテラルが用意されているので明示的に書きなさいという言語設計なのでしょう。

質問1に関連して数値リテラルを細かく分ける統一性よりも、記述の簡潔さを優先したのだと思います。

投稿2017/09/26 06:52

shimitei

総合スコア799

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2017/09/26 07:06 編集

「there are no implicit widening conversions for numbers」は私も見つけたのですが、var l: Long = 3 はエラーにならないんですよね。(ドキュメントが更新されていないのでしょうか?)
shimitei

2017/09/26 07:19

確かにそれはドキュメントと合っていませんね。
shimitei

2017/09/26 08:01

言語仕様を見てもTODOだらけで、細かい所はドキュメントに出ていませんね。 http://jetbrains.github.io/kotlin-spec/#_decimal_literals decimal literalはInt型であるけれども「TODO: it is more complicated」のため一見矛盾することが通ってしまうようです。
mosa

2017/09/26 08:34

ご回答ありがとうございます。 「小さい型から大きい型への暗黙的な変換は行わない」という記載しかないのですが、実際の挙動も合わせてみると、逆に「decimal literalにおいて、大きい型から小さい型への暗黙的な変換は行う」ととらえてよい感じですかね。 加えて、なぜか「Int型であるはずのdecimal literalはLong型への暗黙的な変換は行う」ということになりますかね。
mosa

2017/09/26 08:49

fuzzballさん  コメントありがとうございます。 なんだかもうついていけなくなってきました。。。 val l: Long = 0 println(l.equals(0)) // コンパイル通る(false) println(l == 0) // コンパイル通らない
shimitei

2017/09/26 09:12

まとめるとその通りです。 いまいち整合性が取れてないですが、decimal literalは代入時には暗黙的に変換されるのでしょう。
mosa

2017/09/28 01:32

ありがとうございます。いったんクローズしますが、引き続き何か情報がありましたらコメントなどいただけると幸いです。 Kotlinのissueなども少しずつ見ていけるようにしたいと思います。 ありがとうございました。
guest

0

回答2

Kotlinは暗黙の型変換を行いません。
val s: Short = 3の3をShortと見做すのは型推論であって型変換ではありません。

他は分からないです。

投稿2017/09/26 01:03

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mosa

2017/09/26 05:35

ご回答ありがとうございます。 すみません。私の「型推論」と「暗黙の型変換」の理解がそもそも誤っているのかもしれません。 1.「val s:Short」は型を明記しているので、sは「型推論」されるわけではないと思っています。 2.「3 is Int」が「true」となり、「3 is Short」が「Incompatible types」となるところを見ると、リテラル「3」はInt型であり、Short型であるsにInt型の3を代入できているので、「暗黙の型変換」に見えてしまいます。
fuzzball

2017/09/26 06:06 編集

すみません、回答は私の勘違いですね。マイナス付けておいて下さいw ただ、暗黙の型変換ではなく、Int から Shortへの明示的な型変換だと思います。 【追記】あ、明示的だと 3.toShort() になるんですかね‥。
mosa

2017/09/26 08:22

ああ、なるほどです。「3.toShort() is Short」は「true」になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問