Genericsにenum型を指定する方法がわからず試行錯誤してみた。
enum型で定義した単位を選択するビューを汎用化するためにGenericsを使用してみたが、enum型のみに限定するための制約がよくわからず苦労した。
まず試したこととしては、とりあえず制約にenumを指定してみた。
struct GenericView<T:enum>: View // エラー
// or
struct GenericView<T>: View where T: enum // エラー
で、案の定エラーとなった。enumは型ではないのでそらそうか。
C#の場合は enum は System.Enum を継承しているような気がしたので、Swiftでも似た感じになっていないか探してみるが見つからない
struct GenericView<T:System.Enum>: View // System.Enum的なものがみつからない
// or
struct GenericView<T>: View where T: System.Enum // System.Enum的なものがみつからない
ただし、enumで継承されるいくつかのprotocolは見つかった。
なので、それを利用して制約をかけてみた。
// 単位を選択するビュー
// Unit = 単位型
// unit: Binding<Unit?> = 入出力
// units: [Unit] = 選択肢
struct UnitSelectView<Unit>: View where Unit: RawRepresentable, Unit.RawValue == String, Unit: Hashable
{
@Binding private var m_unit: Unit?
private let m_units: [Unit]
init(
unit: Binding<Unit?>,
units: [Unit]
)
{
self._m_unit = unit
self.m_units = units
}
var body: some View
{
VStack
{
Form
{
Picker( "単位", selection: self.$m_unit )
{
ForEach( self.m_units, id: \.self )
{ ( unit: Unit ) in
Text( "\(unit.rawValue)" )
.tag( unit as Unit? )
}
}
}
}
}
}
Genericsの中で使用するメンバーに応じて、protocolを探して追加しなければならないのが、ちょっと面倒。
とりあえず目的は達成できたものの、他にいい方法はないものか?