Kotlin ビット演算を使った綺麗な状態管理

ビット演算を上手に使うと今まで別のプロパティとして持たせていた、 ユーザーの「性別」「会員タイプ」「支払方法」などの複数の状態管理を一つのプロパティとして分かりやすく扱う事ができます。 KotlinではJavaの時とビット演算のやり方が変わったもののとても分かりやすくなりました。

この記事ではKotlinの新しいビット演算のやり方から、 Enumと組み合わせた便利な活用方法を紹介します。


目次

  1. ビット演算とは
  2. Kotlinのビット演算
  3. 2進数による状態管理
  4. Enumと組み合わせる

ビット演算とは

ビット演算とは2進数を利用した演算方式です。 2進数で扱い、その数値を1バイトずつ(1桁ずつ)チェックし、 0か1かでフラグが立っているかいないかの判断をします。


Kotlinのビット演算

2進数のビット演算は以下の様に行われます。 kotlinでは2進数を表す時、頭に 0b をつけます。


演算子 X Y 結果 説明
AND(論理積) 101 111 101 両方1の箇所のみ1になる
OR(論理和) 101 111 111 どちらか1の箇所が1になる
XOR(排他的論理和) 101 111 010 0と1の箇所が1になる
ビット反転 101 - 010 0と1の箇所が反転


2進数による状態管理

このビット演算を活用すると、 例えばユーザーの中で「男性」かつ「有料会員」だけ抽出する様なif文をとてもシンプルに書く事ができます。

if(user.type == Sex.male + User.premium) {
    // todo...
}

実際にKotlinの Intent.flag では同じ様にビット演算が用いられています。

以下一部抜粋

public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288;
public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608;
public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432;
public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576;
public static final int FLAG_ACTIVITY_LAUNCH_ADJACENT = 4096;

それぞれの一見意味不明な値は2進数にして利用されています。


Enumと組み合わせる

KotlinのEnumを使えばより型安全に実装すことができます。

KotlinでのEnumの使い方を以前紹介していたので合わせてどうぞ。


kotlin enumを使った安全な実装

Kotlinの場合 rawValue と書かなければいけないのがナンセンスですが。 エラーが起きる可能性が高かったり、名前空間を持たないよりは安全?かと思います。 以下が例になります。

class User {
    var type = 0
}

enum class Type(val rawValue: Int) {
    NO_STATUS(0b0000),
    SEX_MALE(0b0001),
    SEX_FEMALE(0b0010),
    TYPE_PREMIUM(0b0100),
    TYPE_FREE(0b1000);
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // 利用時
    val user = User()
    user.type = Type.SEX_MALE.rawValue + Type.TYPE_PREMIUM.rawValue

    if(user.type == Type.SEX_MALE.rawValue + Type.TYPE_PREMIUM.rawValue) {
        // todo...
    }
}

最後に

公式の様にやってももちろんいいのですが、今回はEnumを利用する事で入る値を制限して安全な対策を取る事を意識して書きました。

誰かのお役に立てたら嬉しいと思います。 最後まで読んでいただき有難う御座いました。

0 コメント