はじめに
この記事ではJavaに限った話をします。
先日、以下の記事を書きました(タイトル変更してます)。
この記事で、以下のように三項演算子を良い例として挙げました。
String userType = isAdmin ? "管理者" : "一般";
しかし、三項演算子は読みにくいという反応が結構ありました。あくまでシンプルな例として挙げたつもりだったのですが、説明不足だったので、別途記事を書きます。
三項演算子を使っていいのは、単純なもののみに限られるのが自分の中での結論です。
三項演算子とは
三項演算子(ternary operator)は以下のような形をしています。
<条件式> ? <trueのときの値> : <falseのときの値>
どの書き方ならよいかの話をする前に、自分が「どこまでならよい」と感じているのか、その例を書きます。
/*
* 白(ほぼ問題なし)
*/
String userType = isAdmin ? "管理者" : "一般";
String userType = user.isAdmin() ? "管理者" : "一般";
UserType userType = user.isAdmin() ? UserType.ADMIN : UserType.NORMAL;
String userName = user.isAdmin() ? "管理者" : user.getName();
/*
* 白に近いグレー
*/
return user.getType() == UserType.GUEST ? "ゲストユーザ" : user.getName();
/*
* 黒に近いグレー
*/
String userName = user.getType() == UserType.GUEST ? "ゲストユーザ" : user.getName();
/*
* 黒(アウト)
*/
String userName = user.getType() == UserType.GUEST ? "ゲスト" : user.getType() == UserType.ADMIN ? "管理者" : user.getName() + "さん";
何が基準か
三項演算子の定義に戻ります。
<条件式> ? <trueのときの値> : <falseのときの値>
先程の例で、どのようなパターンが良いのか、悪いのかは、以下のように分類できます。
- 白(ほぼ問題なし)
- 条件式
- boolean変数
- booleanを返すメソッド
- true/falseのときの値
- 定数
- enum
- getterなど単純な呼び出し
- 条件式
- グレー
- 条件式に
==
や!=
での比較が入る
- 条件式に
- 黒(アウト)
- ネストしている
- true/falseのときの値が、単純な呼び出し以外
三項演算子が嫌われがちなのは、どこまでが条件式なのか、どこまでがtrueのときの値なのか、頭の中で字句解析、文法解析するコストが高いからです。また、 ==
や !=
での比較が入るとよくないのは、代入の =
と見間違えて、一瞬混乱するからです。
なので、単純な書き方以外は避けるようにしています。
どのように書くべきか
以下のように書くこともできますが、後ろ向きな解決案なので、自分は好きではありません。
String userName; // ここでの初期化は無駄なのでしない
if (user.getType() == UserType.GUEST) {
userName = "ゲスト";
} else if (user.userType() == UserType.ADMIN) {
userName = "管理者";
} else {
userName = user.getName() + "さん";
}
自分なら以下のように、メソッドを作ります。この場合はUserクラスのメソッドとして実装できますが。
なお、今回は元の条件式と合わせるためにif文にしましたが、enumの場合はswitch文を使うことが多いです。
private String getName(User user) {
if (user.getType() = UserType.GUEST) {
return "ゲスト";
} else if (user.getType() == UserType.ADMIN) {
return "管理者";
} else {
return user.getName() + "さん";
}
}
// 呼び出し元
String userName = getName(user);
おわりに
自分が思っていたより、読みにくくなるパターンのほうが多かったです。三項演算子を禁止するのはやりすぎだと思いますが、単純なもの以外は使わないくらいでいいと思います。