Swift.Range/ClosedRangeはCodable
Swiftは範囲を表現する型にRange
/ClosedRange
を用意してる。
CountableRange
とCountableClosedRange
というそれぞれのwhere条件を持つtypealiasもあるが、ここでは同じものだと思ってほしい。
Range
/ClosedRange
のBound
が Encodable
/Decodable
である時、Range
/ClosedRange
もEncodable
/Decodable
にconformする。
つまり、Codable
である。
では、Range
/ClosedRange
を JSONEncoder
と JSONDecoder
に通すと、どんなフォーマットになるだろう?
試してみましょう。
※encode/decodeはカスタマイズしないものとする
環境
- Apple Swift version 5.7.2 (swiftlang-5.7.2.135.5 clang-1400.0.29.51)
- Xcode Version 14.2 (14C18)
- Playground
Range
Range
は半開区間 (左閉右開) である。
RangeをJSONファイルで保存する
import Foundation let fileManager = FileManager.default let encoder = JSONEncoder() let path = NSTemporaryDirectory() print(path) do { struct Content: Codable { var name: String var value: Range<Int> } let contents: [Content] = [ .init(name: "0..<9", value: 0..<9), .init(name: "10..<13", value: 10..<13), .init(name: "14..<39", value: 14..<39), ] do { let data = try encoder.encode(contents) let json = try JSONSerialization .jsonObject(with: data, options: .fragmentsAllowed) print(json) let location = URL(fileURLWithPath: path) .appending(path: "Range.json") try data.write(to: location) } catch { print(error) } }
結果
[ { "name":"0..<9", "value":[ 0, 9 ] }, { "name":"10..<13", "value":[ 10, 13 ] }, { "name":"14..<39", "value":[ 14, 39 ] } ]
ClosedRange
ClosedRange
は閉区間である。
ClosedRangeをJSONファイルで保存する
import Foundation let fileManager = FileManager.default let encoder = JSONEncoder() let path = NSTemporaryDirectory() print(path) do { struct Content: Codable { var name: String var value: ClosedRange<Int> } let contents: [Content] = [ .init(name: "0...9", value: 0...9), .init(name: "10...13", value: 10...13), .init(name: "14...39", value: 14...39), ] do { let data = try encoder.encode(contents) let json = try JSONSerialization .jsonObject(with: data, options: .fragmentsAllowed) print(json) let location = URL(fileURLWithPath: path) .appending(path: "ClosedRange.json") try data.write(to: location) } catch { print(error) } }
結果
[ { "name":"0...9", "value":[ 0, 9 ] }, { "name":"10...13", "value":[ 10, 13 ] }, { "name":"14...39", "value":[ 14, 39 ] } ]
つまり...
Range
/ClosedRange
をencodeした結果は [a, b]
となり、フォーマットは共通である。
encode/decodeにご注意ください。
追記
2022/12/15 23:55
Range
を Codable
にconformさせるプロポーザルを教えてもらいました。
Add Codable conformance to Range types