[Realm][Swift] Realm に Decimal が導入されました

     

TAGS:

⌛️ < 1 min.
Realm で Decimal を扱いたくて、独自タイプを導入していましたが、Realm に Decimal が導入されましたので、説明します。

導入が待てなくて、自分で作ったりもしていました。

[Realm][Swift] 新しいタイプの導入

Decimal128 が導入

Realm 10.0.0 で、10進数を正確に表現することができる タイプが導入されました。

Realm の リリースノートは、こちら

導入されたタイプは、Decimal128 というタイプです。Swift が提供する Decimal とは、内部表現が異なります。

Realm のドキュメントは、こちら

Decimal128 とは

Swift の提供する Decimal は、仮数部が 最大 38ビットで、指数部では -128 ~ 127 を表現することができます。

Realm が提供する Decimal128 は、仮数部が 最大 34ビットで、指数部では、-6143 ~ 6144 を表現することができます。

# 家計簿アプリを作ろうする視点では、大差ないです。

MEMO

ちなみに、指数部をのぞいて考えるとすると、

34ビットでは 17,179,869,183 を表すことができます。170億ですね。

38ビットでは、274,877,906,943 を表すことができ、2740億を 表現することができます。

Decimal128 の使い方

他の Realm がサポートしているタイプと同様に使うことができます。

例えば、以下のように属性の1つとして定義して使います。

Decimal128 使用例


public class MCTransaction: Object, Identifiable {
    @objc public dynamic var id: String
    @objc public dynamic var date: Date
    @objc public dynamic var internalAmount: Decimal128 = 0
...
}

Realm がサポートするタイプなので、他要素へのリンクではなく、内部に保持されます。

Decimal と Decimal128 との相互変換

Swift の提供する Decimal と Realm の提供する Decimal128 の相互変換も用意されています。

そのための変換は、Decimal128 側に用意されています。

Decimal Decimal128 の変換


// Decimal128 to Decimal
let decimal128value:Decimal128 = 10
let decimalValue = decimal128Value.decimalValue

// Decimal to Decimal128
let newDecimal128Value = Decimal128(value:decimalValue)

Decimal で Decimal128 をラップする

Decimal128 は、Realm 固有のタイプですので、それをそのままアプリケーション内部で使ってしまうと、アプリケーションや内部ロジックが Realm に依存することになってしまいます。
Swift の提供するタイプに揃えたかったので、DB の内部では Decimal128 を使って保持しますが、外部とは Decimal を使ってやりとりするようにしました。

独自タイプを使っていた時と同様に、Decimal でのやり取りを行う getter/setter を定義することで、外部からは、Decimal のみで使うことができます。

example code


public class MCTransaction: Object, Identifiable {
  @objc public dynamic var id: String
  @objc public dynamic var date: Date
  @objc public dynamic var internalAmount: Decimal128 = 0
  var amount: Decimal {
    get {
      return internalAmount.decimalValue
    }
    set {
      self.internalAmount = Decimal128(value: newValue)
    }
  }
...
}

アプリケーションからは、MCTransaction.amount にアクセスすることで、Decimal を扱いますが、Realm は、Decimal128 としての internalAmount が保存対象です。

まとめ: Realm に Decimal が導入されました!

Realm に Decimal が導入されました!
  • Realm 10.0 以降で 10進数を正確に扱うことのできる Decimal が導入されました
  • Decimal128 という Realm が定義するタイプが導入され、Swift の Decimal とは定義が異なります
  • Decimal128 と Decimal との相互変換は、Decimal128 側が定義しています

説明は以上です。
不明な点やおかしな点ありましたら、ご連絡いただけるとありがたいです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です