有没有办法轻松地将一串键值对解析成scala案例类?
例如,来自以下字符串
"consumer_key=1234ABC, consumer_secret=12345ABC"
Run Code Online (Sandbox Code Playgroud)
成
case class Auth(consumerKey: String, consumerSecret: String)
Run Code Online (Sandbox Code Playgroud)
甚至
"consumer_key=1234ABC, consumer_secret=12345ABC"
Run Code Online (Sandbox Code Playgroud) 我在代码中大量使用了case类,回复了case类的底层相等定义,以便正确运行.然后我发现我需要将另一个字段成员添加到案例类.
var在case类中添加一个字段成员,它会弄乱case类的相等属性吗?var一次字段值,那么在案例类进入任何集合或进行相等比较之前,不会发生任何重新分配,那么这仍然会破坏相等行为吗?我正在尝试这样做:
trait IdentifiableModel[T] {
self: { def copy(id: ObjectId): T } =>
val id: ObjectId
}
Run Code Online (Sandbox Code Playgroud)
我发现其他一些相关的问题试图做类似的事情,但他们并没有真正回答这个问题.在我的例子中,我正在尝试复制所有共享id值的IdentifiableModel的case类子类
我正在尝试编写一个泛型方法来迭代案例类的字段:
case class PriceMove(price: Double, delta: Double)
def log(pm : PriceMove) { info("price -> " + price + " delta -> " + delta)}
我需要log能够处理任何案例类.什么只需要log处理case类的参数类型和实际的泛型字段迭代代码?
当具有带类型参数的case类时,我看不到如何调用该tupled方法.它似乎与apply和找到unapply.
scala> case class Foo[T](x:T, y:T)
defined class Foo
scala> Foo.apply[Int] _
res1: (Int, Int) => Foo[Int] = <function2>
scala> Foo.unapply[Int] _
res2: Foo[Int] => Option[(Int, Int)] = <function1>
scala> Foo.tupled[Int] _
<console>:10: error: value tupled is not a member of object Foo
Foo.tupled[Int] _
^
Run Code Online (Sandbox Code Playgroud)
对于发生了什么有什么想法?
我有一个案例类定义如下:
case class StreetSecondary(designator: String, value: Option[String])
Run Code Online (Sandbox Code Playgroud)
然后我定义一个显式的伴侣对象:
object StreetSecondary {
//empty for now
}
Run Code Online (Sandbox Code Playgroud)
定义显式伴随对象StreetSecondary的行为导致编译器生成"隐含伴随对象"丢失; 即替换为无法访问编译器生成的版本.例如,该tupled方法可通过此隐式伴随对象在案例类StreetSecondary上使用.但是,一旦我定义了显式伴随对象,该tupled方法就会"丢失".
那么,我需要定义/添加/更改上面的StreetSecondary显式伴随对象,以重新获得所有丢失的功能,并替换编译器提供的隐式伴随对象?我想要的不仅仅是tupled恢复的方法.我想要unapply恢复所有功能(例如,包括提取器/ ).
感谢您提供的任何指导/指导.
更新1
我已经做了足够的搜索来发现几件事:
A)必须在其案例类之前定义显式伴随对象(至少在Eclipse Scala-IDE工作表中就是这种情况,并且代码在IntelliJ IDE的工作表中不起作用,无论哪个先出现).
B)有一个强制tupled工作的技术技巧(谢谢drstevens):(StreetSecondary.apply _).tupled虽然这解决了特定的tupled方法问题,但它仍然没有准确或完整地描述scala编译器在隐式伴随对象中提供的内容.
C)最后,可以定义显式伴随对象以扩展与主构造函数的参数的签名匹配的函数,并返回案例类的实例.它看起来像这样:
object StreetSecondary extends ((String, Option[String]) => StreetSecondary) {
//empty for now
}
Run Code Online (Sandbox Code Playgroud)
同样,我仍然不能准确或完整地描述scala编译器在隐式伴随对象中提供的内容.
我有一个包含许多成员的案例类,其中两个是非原始的:
import com.twitter.util.Duration
case class Foo(
a: Int,
b: Int,
...,
y: Int,
z: Int,
timeoutSeconds: Duration,
runtimeMinutes: Duration)
Run Code Online (Sandbox Code Playgroud)
我想将以下JSON反序列化为此case类的实例:
{
"a": 1,
"b": 2,
// ...
"y": 42,
"z": 43,
"timeoutSeconds": 30,
"runtimeMinutes": 12,
}
Run Code Online (Sandbox Code Playgroud)
通常,我会写json.extract[Foo].然而,MappingException由于timeoutSeconds和,我得到了明显的runtimeMinutes.
我看过FieldSerializer,它允许在AST上进行字段转换.但是,它不够,因为它只允许AST转换.
我也看过扩展CustomSerializer[Duration],但没有办法反省哪个JSON密钥正在被处理(timeoutSeconds或runtimeMinutes).
我也可以尝试延长CustomSerializer[Foo],但后来我将有很多的样板代码,用于提取值a,b,..., z.
理想情况下,我需要一些PartialFunction[JField, T]作为反序列化器的东西,以便我可以写:
{
case ("timeoutSeconds", JInt(timeout) => timeout.seconds
case ("runtimeMinutes", JInt(runtime) => …Run Code Online (Sandbox Code Playgroud) 假设我有一个类似的案例类
case class Person(fname:String, lname:String, nickName:Option[String] = None)
Run Code Online (Sandbox Code Playgroud)
在创建像Person("John","Doe")这样的实例时,我希望将nickName自动分配给fname,如果没有给出.例如:
val p1 = Person("John", "Doe")
p1.nickName.get == "John"
val p2 = Person("Jane", "Doe", "Joe")
p2.nickName.get == "Joe"
Run Code Online (Sandbox Code Playgroud)
如何实现从另一个字段自动分配一个字段?
在repl中尝试以下解决方案.我认为这与repl有关
scala> case class Person(fname: String, lname:String, nickName:Option[String])
defined class Person
scala> object Person { def apply(fname:String, lname:String):Person = {Person(fname, lname, Some(fname))}}
console:9: error: too many arguments for method apply: (fname: String, lname: String)Person in object Person
object Person { def apply(fname:String, lname:String):Person = {Person(fname, lname, Some(fname))}}
Run Code Online (Sandbox Code Playgroud) 我有一些case类,它们的tupled伴随对象中定义了一个方法.从下面的代码对象中可以看出,它只是代码重复.
case class Book(id: Int, isbn: String, name: String)
object Book {
def tupled = (Book.apply _).tupled // Duplication
}
case class Author(id: Int, name: String)
object Author {
def tupled = (Author.apply _).tupled // Duplication
}
Run Code Online (Sandbox Code Playgroud)
从另一个问题(scala自我类型可以强制执行案例类类型),似乎我们不能强制将特征的自我类型作为案例类.
有没有办法定义一个Tupled可以应用如下的特征(比如说)?
// What would be value of ???
trait Tupled {
self: ??? =>
def tupled = (self.apply _).tupled
}
// Such that I can replace tupled definition with Trait
object Book extends Tupled {
}
Run Code Online (Sandbox Code Playgroud) 如何从表示该字段的给定String值中提取案例类的字段值.
例如:
case class Person(name: String, age: Int)
val a = Person("test",10)
Run Code Online (Sandbox Code Playgroud)
现在这里给出一个字符串name 或age我想从变量中提取值a.我该怎么做呢?我知道这可以用反射完成,但我不确定如何?