我正在尝试创建一个类型类,允许为给定类型选择一个字段。这是我到目前为止所做的,但编译器无法找到Selector.Aux
case class AddressKey(street: String, city: String)
trait AddressKeySelector[A] {
def addressKey(v: A): AddressKey
def addressKeyColumnName: String
}
object AddressKeySelector {
implicit def typeAddressKeySelector[A, Repr <: HList, K](
implicit gen: Generic.Aux[A, Repr],
reprSelector: Selector.Aux[Repr, K, AddressKey]): AddressKeySelector[A] =
new AddressKeySelector[A] {
override def addressKey(v: A): AddressKey = reprSelector(gen.to(v))
override def addressKeyColumnName: String = ???
}
}
它会像这样使用
case class MyType(addressKeyField: AddressKey, otherField: String)
val data = MyType(AddressKey("addr", "city"), "other")
val addrKey = AddressKeySelector[MyType].addressKey(data)
// addrKey: AddressKey = AddressKey(addr,city)
val addrField = AddressKeySelector[MyType].addressKeyColumnName(data)
// addrField: String = addressKeyField
只有当一个且只有一个字段具有AddressKey类型时,这才能正常工作。关于如何实现它的任何想法?
答案 0 :(得分:2)
ops.hlist.Selector
没有Aux
,因此我假设您正在使用该LabelledGeneric
。如果您要提取字段名称,则可能需要使用ops.record.Selector
和Selector.Aux[Repr, K, AddressKey]
。但是Selector
仍然无效,因为K
只能按&#34;键&#34; (AddressKey
)而不是&#34;价值&#34; (import shapeless._, ops.record._
trait AddressKeySelector[A] {
def addressKey(v: A): AddressKey
def addressKeyColumnName: String
}
object AddressKeySelector {
def apply[A](implicit sel: AddressKeySelector[A]): sel.type = sel
implicit def typeAddressKeySelector[A, Repr <: HList, K <: Symbol, Swapped <: HList](
implicit
gen: LabelledGeneric.Aux[A, Repr],
swap: SwapRecord.Aux[Repr, Swapped],
swappedSelector: Selector.Aux[Swapped, AddressKey, K],
reprSelector: Selector.Aux[Repr, K, AddressKey]
): AddressKeySelector[A] =
new AddressKeySelector[A] {
override def addressKey(v: A): AddressKey = reprSelector(gen.to(v))
override def addressKeyColumnName: String = swappedSelector(swap()).name
}
}
),当您按值搜索密钥时。
理想情况下,我认为你会像这样实现它:
Hlist
但some reason无效。
所以我认为你最好的选择是自己实现价值搜索。它相对简单。你可以从ops.hlist.Selector
中获取灵感。请记住,LabelledGeneric
发出的labelled.FieldType[Key,Value]
中的每个条目都被编码为Key
,并且您可以获得Witness.Aux[Key]
的运行时值(换句话说:字段名称)public async Task Send(string userId, string devicePushToken, string content)
{
string json = JsonConvert.SerializeObject(new
{
tokens = new[] {devicePushToken},
profile = "yourprofile",
notification = new
{
message = content
}
});
var restClient = new RestClient("https://api.ionic.io/");
var restRequest = new RestRequest("push/notifications", Method.POST);
restRequest.AddHeader("Accept", "application/json");
restRequest.AddParameter("application/json", json, ParameterType.RequestBody);
restRequest.AddParameter("Authorization",
"Bearer APIKEY",
ParameterType.HttpHeader);
await restClient.ExecuteTaskAsync(restRequest);
}
。