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

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

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

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

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

Q&A

解決済

1回答

3025閲覧

Kotlin ポリモフィズムがうまく機能しない

guijiu

総合スコア36

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

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

0グッド

0クリップ

投稿2021/04/16 02:11

編集2021/04/16 02:26

##1. 事象
「Androidアプリ開発の教科書 Kotlin対応(初版第2刷)」を写経しています。
サンプルプログラムの中で、 ジェネリックのmutablMap<String, Any>で、ポリモフィズムがうまく機能しない事象を見つけました。
( p179 第8章 リストビューのカスタマイズ リスト8.3より必要と思われる部分を抜粋し、事象を説明します。)

イメージ説明

 ソースコードの抜粋を示します。

Kotlin

1fun main(args: Array<String>) { 2 val menuList: MutableList<MutableMap<String, Any>> = mutableListOf() 3 var menu = mutableMapOf("name" to "唐揚げ定食", "price" to 800, "desc" to "若鳥の唐揚げにサラダ") 4 menuList.add(menu) 5}

 3行目の部分にあるmenuの型は推定の結果、“var menu: MutableMap<String, out {Comparable*> & java.io.Serializable}>”です。

 このMutableMapの要素menuを4行目のmenuListに追加しようとした際に、型が合わない(Kotlin: Type mismatch: inferred type is MutableMap<String, out {Comparable<*> & java.io.Serializable}> but MutableMap<String, Any> was expected
)とエラーを出力しました。

##2.質問
menuListは型が MutableList<MutableMap<String, Any>>なので、型がMutableMap<String, out {Comparable> & java.io.Serializable}>であるmenuListにmenuを追加できると思うのですがエラーになってしまいます。
Anyはすべての型の親なのに、なぜ
out {Comparable
> & java.io.Serializable}>**を受け入れることができないのでしょうか?

 (なお、半年か1年ほど前に写経した同じサンプルプログラムが現存していますが、それは今でもエラーを出力しません。Androidのプロジェクトに含まれているbuild.gradle(Project)を調べてみると当時のKotlinコンパイラのバージョンは1.3.72で、現在のは1.4.32です。もしかするとコンパイラが原因でしょうか?)

##3.応急対応
次のように3行目の変数menuの型を“:MutableMap<String, Any>”と指定することで、エラーは解消されました。

var menu:MutableMap<String, Any> = mutableMapOf("name" to "唐揚げ定食", "price" to 800, "desc" to "若鳥の唐揚げにサラダ")

ご指導のほど、よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

menuListは型が MutableList<MutableMap<String, Any>>なので、型がMutableMap<String, out {Comparable*> & java.io.Serializable}>であるmenuListにmenuを追加できると思うのですがエラーになってしまいます。

これが間違いで、一般にBがAにキャストできるときT<B>がT<A>にキャスト可能とは限りません。
例えば

kotlin

1 val mutableMap: MutableMap<String, String> = mutableMapOf("key" to "value") 2 val map: MutableMap<String, Any> = mutableMap

こういった操作が可能な場合、それに続いて

kotlin

1map.add("integer", 1)

というような操作が続いた場合、mapの型からすれば適当な操作ですがその実体であるmutableMapの型からすると不適当な操作です。そのため、val map: MutableMap<String, Any> = mutableMapが禁止されています。

詳しくは分散 共変 反変などで調べてください。

コンパイルエラーの有無が違うのは型推論の結果の違いではないでしょうか(未確認)

投稿2021/04/16 02:53

yudedako67

総合スコア2047

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

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

guijiu

2021/04/16 04:17

ご教示ありがとうございます。 ”分散 共変 反変”、新しい言葉を知ったような気がします。 調べ直し、わからないようであれば、新たに質問させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問