2017年7月7日金曜日

Kotlin スタートブックを読みました。



正誤表 http://www.ric.co.jp/book/error/error1039.html

Java をある程度できる人にとって、手っ取り早く Kotlin で読み書きできるようになれる入門書だと思いました。 第II部は特によかったです。

以下、もやもやした点と、正誤表に載っていなかった気になる点について書いておきます。





p46 4章 1.4
「原則として val を使用し、再代入を極力避けるべきです。」
とだけあってなぜなのか書かれていませんでした。わかる人にはわかりますが、わからない人にはわからないと思います。



p49 4章 2.1
イミュータブルという単語がいきなり出てきて特に説明もないので、この本を読む人はイミュータブルの意味を知っていて当然ということのようです。
カタカナでイミュータブルと書かれるともにょもにょしますが、まぁ決めの問題なので書く人の好きなようにすればよいと思います。こういう単語の翻訳は難しいですね。



p51 4章 2.1
trimMargin() は行頭の空白と続く marginPrefix を消してくれる関数ですが、本書での説明だと | だけ消すかのように読み取れました。
https://kotlinlang.org/docs/reference/basic-types.html
trimMargin() の marginPrefix のデフォルトが | であることも触れた方がよいと思いました。



p59 4章 3.2
myFavoriteInt() の実体が書かれていないので混乱しましたが、Int を返す関数のようです。
「条件分岐の部分に、定数以外を指定できるからです」
とあったので、条件式を書けるのかと思ってしまいました。そうではなく評価した結果の値が定数のように扱われるようでした。
つまり
  1. when (x) {  
  2.     1 -> "one"  
  3.     x % 2 == 0 -> "odd"  
  4.     else -> "even"  
  5. }  
のように書けるのかと思ってしまったのですが、以下のように書かないといけません。
  1. val x = 4  
  2. when {  
  3.     x == 1 -> "one"  
  4.     x % 2 == 0 -> "odd"  
  5.     else -> "even"  
  6. }  




p243 15章 2
view_article.xml のルート View を RelativeLayout にしていますが、 これを FrameLayout を継承した ArticleView に追加するのは View 階層の無駄なので、ここでは ルートを <merge> にして ArticleView が RelativeLayout を継承する形にするのが適切だと思います。



p245 15章 2
そもそも lazy の例として、カスタムビューで子 View のインスタンスを取得するのは適切ではないと思います。
Java で書くときも以下のように final field にしてコンストラクタで初期化するようにしています。
  1. public class ArticleView extends RelativeLayout {  
  2.       
  3.     private final ImageView profileImageView;  
  4.     private final TextView titleView;  
  5.     private final TextView userNameTextView;  
  6.       
  7.     public ArticleView(Context context) {  
  8.         this(context, null);  
  9.     }  
  10.   
  11.     public ArticleView(Context context, AttributeSet attrs) {  
  12.         this(context, attrs, 0);  
  13.     }  
  14.   
  15.     public ArticleView(Context context, AttributeSet attrs, int defStyleAttr) {  
  16.         super(context, attrs, defStyleAttr);  
  17.   
  18.         LayoutInflater.from(context).inflate(R.layout.view_article, this);  
  19.         profileImageView = (ImageView) findViewById(R.id.profile_image_view);  
  20.         titleView = (TextView) findViewById(R.id.title_text_view);  
  21.         userNameTextView = (TextView) findViewById(R.id.user_name_text_view);  
  22.     }  
  23. }  
これを Kotlin でもやるなら以下のようになって、そもそも lazy はいりません。
  1. class ArticleView @JvmOverloads constructor(context: Context,  
  2.                                             attrs: AttributeSet? = null,  
  3.                                             defStyleAttr: Int = 0) : RelativeLayout(context, attrs, defStyleAttr) {  
  4.   
  5.     private val profileImageView: ImageView  
  6.     private val titleView: TextView  
  7.     private val userNameTextView: TextView  
  8.   
  9.     init {  
  10.         LayoutInflater.from(context).inflate(R.layout.view_article, this)  
  11.         profileImageView = findViewById(R.id.profile_image_view) as ImageView  
  12.         titleView = findViewById(R.id.title_text_view) as TextView  
  13.         userNameTextView = findViewById(R.id.user_name_text_view) as TextView  
  14.     }  
  15. }  
Fragment で getArguments() から値を取り出す場合のほうが lazy の例として適切だと思います。



p247 15章 2
p253 15章 3
ArticleView のコンストラクタに applicationContext を渡していますが、よくないです。
理由は View のコンテキストに Application Context を渡すとテーマが適用されない に書きました。



p251 15章 3
私だったら Adapter が持つ List
は外部に公開しないようにするかな。



p274 16章
Context に拡張関数で toast() を生やす方法、Window を持たない Context (Application Context とか Service の Context とか)でうっかり呼び出すと落ちるから、個人的にはあんまり適切な例ではないと思っています。
Toast の Context は Application Context でも OK でした。最近 Toast 使わないからうっかりしてました。 Toast では Context をパッケージ名の取得と string とかのリソースの取得にしか使ってないので Window は関係ありませんでした。 Application Context を渡すと Window が無くて死ぬのは Dialog でした。




0 件のコメント:

コメントを投稿