我需要为一堆全部派生自单个特征的案例类提供类型类实例,但据我了解,Scala 编译器需要特定类的实例,并且不会沿继承层次结构上升。所以这段代码:
trait Base
sealed trait Child extends Base
case class Concrete() extends Child
trait Printable[A] {
def print(value: A): String
}
object WtfTrait {
def print[A](x: A)(implicit ev: Printable[A]) = {
println(ev.print(x))
}
implicit val printableBase = new Printable[Base] {
override def print(value: Base): String = value.toString
}
val x = Concrete()
print(x)
}
Run Code Online (Sandbox Code Playgroud)
编译时不会出现错误读取could not find implicit value for parameter ev: Printable[Impl]。有没有办法为基本特征定义单个类型类实例,并通过使用 Shapeless 或其他东西来避免重复。
当隐式类声明中发生转换时,编译器未能选择正确的隐式转换方法。在下面的示例中,我有一个Foo[T]类和一个隐式Helper类,它采用 aFoo并提供一个print方法。该 print 方法调用show,它本身是一个由 on 隐式转换提供的方法Foo。
问题是有两种可能的转换提供show:一种转换Foo[T]为 a Bar[T],另一种转换Foo[Array[T]]为 a BarArray[T]。这个想法是,当我们有一个Foo包含数组的时候,我们想要应用更具体的BarArray转换。据我了解,编译器首先选择具有最具体类型的转换。
这在正常上下文中起作用,如下例所示,但print在隐式Helper类中的方法的上下文中中断。在那里,show调用了相同的方法,因此我希望应该应用相同的转换。然而,在这种情况下,编译器总是选择Bar转换,即使它有Foo[Array[T]]并且应该选择BarArray转换。
出了什么问题?
最小失败代码示例:
package scratch
import scala.language.implicitConversions
class Foo[T](val value: T) {}
object Foo {
implicit def fooToBar[T](foo: Foo[T]): Bar[T] = {
new Bar(foo.value)
}
implicit def fooArrayToBarArray[T](foo: Foo[Array[T]]): BarArray[T] = {
new …Run Code Online (Sandbox Code Playgroud) 标题可能很模糊,但这是代码: https: //github.com/amorfis/why-no-implicit
所以有一个工具可以转化Map[String, Any]为简单的案例类。测试通过了,这段代码说明了它的全部内容:
case class TargetData(
groupId: String,
validForAnalysis: Boolean,
applicationId: Int
)
val map = Map(
"groupId" -> "123456712345",
"applicationId" -> 31,
"validForAnalysis" -> true
)
val transformed: TargetData = MapDecoder.to[TargetData](map).transform
Run Code Online (Sandbox Code Playgroud)
这段代码有效。当提供简单的情况时,它很好地创建了案例类实例map
但是,该transform方法必须在“外部”调用 - 就像示例中一样。当我尝试将其移至该MapDecoder.to方法时 - 编译器抱怨缺少隐式。
所以我将代码更改MapDecoder.to为:
def to[A](map: Map[String, Any]) = new MapDecoderH[A](map)
Run Code Online (Sandbox Code Playgroud)
对此:
def to[A](map: Map[String, Any]) = new MapDecoderH[A](map).transform
Run Code Online (Sandbox Code Playgroud)
它停止工作了。这是为什么?为什么在一种情况下提供了隐含的内容,而在另一种情况下则没有提供?所有的变化是我想transform在其他地方调用该方法以MapDecoder.to返回案例类而不是某个转换器。
更新:
to[A]如果我想在要转换的对象内实现方法怎么办?让我们称之为DataFrame,我希望这段代码能够工作:
val df: DataFrame = ... …Run Code Online (Sandbox Code Playgroud) @lucastex 发布了关于Java Elvis操作符的内容,我在Scala中尝试了一些东西以获得相同的效果.
我刚刚将所有内容转换为新的结构类型,?:操作符采用与参数相同类型的对象.所以说:
implicit def toRockStar[B](v : B) = new {
def ?:(opt: => B) = if (v == null) opt else v}
val name: String = "Paulo" // example
Run Code Online (Sandbox Code Playgroud)
为什么name ?: "Lucas"得到"Lucas"并name.?:{"Lucas"}得到Paulo?如果它不是null,那么新结构类型应该返回任何东西的初始值,即"Paulo"在上面的代码中.
我有点困惑.任何解释?
我有以下代码,它使用我正在编写的库中的Unicode字符串类:
#include <cstdio>
#include "ucpp"
main() {
ustring a = "test";
ustring b = "ing";
ustring c = "- -";
ustring d;
d = "cafe\xcc\x81";
printf("%s\n", (a + b + c[1] + d).encode());
}
Run Code Online (Sandbox Code Playgroud)
ustring类实例的encode方法将内部Unicode转换为UTF-8 char*.但是,因为我无法访问char类定义,所以我不确定如何定义隐式类型转换(因此我在使用printf时不必手动调用encode等).
我在理解以下现象方面遇到了一些麻烦:
trait Trait[A] {
def traitType: String
}
object Trait {
implicit val stringTrait: Trait[String] = new Trait[String] {
def traitType: String = "string"
}
implicit val intTrait: Trait[Int] = new Trait[Int] {
def traitType: String = "int"
}
}
class Media[A] {
// works
def mediaType(implicit t: Trait[A]): String = t.traitType
// does not compile
def mediaType: String = implicitly[Trait[A]].traitType
}
object Main {
def main(args: Array[String]) {
val a = new Media[String]
val b = new Media[Int]
println(a.mediaType) …Run Code Online (Sandbox Code Playgroud) 嗨,我有以下数据,并希望将其映射到第二个参数中的第一项.因此对于:
1 -> List((1,11))
1 -> List((1,1), (1,111))
Run Code Online (Sandbox Code Playgroud)
我想要:
(1,11)
(1,1)
Run Code Online (Sandbox Code Playgroud)
当此数据在RDD中时,我可以执行以下操作:
scala> val m = sc.parallelize(Seq(11 -> List((1,11)), 1 -> List((1,1),(1,111))))
m: org.apache.spark.rdd.RDD[(Int, List[(Int, Int)])] = ParallelCollectionRDD[198] at parallelize at <console>:47
scala> m.map(_._2.head).collect.foreach(println)
(1,11)
(1,1)
Run Code Online (Sandbox Code Playgroud)
但是,当它在Map对象(groupBy的结果)中时,我得到以下内容:
scala> val m = Map(11 -> List((1,11)), 1 -> List((1,1)))
m: scala.collection.immutable.Map[Int,List[(Int, Int)]] = Map(11 -> List((1,11)), 1 -> List((1,1), (1,111)))
scala> m.map(_._2.head)
res1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1)
Run Code Online (Sandbox Code Playgroud)
当我映射到整个列表时,我得到了我期望的结果,但是当我打电话给它时
scala> m.map(_._2)
res2: scala.collection.immutable.Iterable[List[(Int, Int)]] = List(List((1,11)), List((1,1), (1,111)))
Run Code Online (Sandbox Code Playgroud)
如果我执行以下任一操作,我也可以得到我想要的结果:
scala> m.map(_._2).map(_.head)
res4: …Run Code Online (Sandbox Code Playgroud) 这是方法的定义,它ExecutionContext隐式使用,并允许客户端覆盖它.两个执行上下文用于测试它:
val defaultEc = ExecutionContext.fromExecutor(
Executors.newFixedThreadPool(5))
Run Code Online (Sandbox Code Playgroud)
线程名称如下所示:'pool-1-thread-1'到'pool-1-thread-5'
而斯卡拉的第二个:
scala.concurrent.ExecutionContext.Implicits.global
Run Code Online (Sandbox Code Playgroud)
线程名称如下所示:'scala-execution-context-global-11'
客户端可以覆盖默认隐式通过:
implicit val newEc = scala.concurrent.ExecutionContext.Implicits.global
Run Code Online (Sandbox Code Playgroud)
不幸的是,只有在没有调用带隐式的方法时,它才可以覆盖():
val r = FutureClient.f("testDefault") //prints scala-execution-context-global-11
Run Code Online (Sandbox Code Playgroud)
不工作:
val r = FutureClient.f("testDefault")() //still prints: pool-1-thread-1
Run Code Online (Sandbox Code Playgroud)
问题是为什么它以这种方式工作?因为它使API的客户端变得更加复杂
以下是运行和播放的完整代码:
object FutureClient {
//thread names will be from 'pool-1-thread-1' to 'pool-1-thread-5'
val defaultEc = ExecutionContext.fromExecutor(
Executors.newFixedThreadPool(5))
def f(beans: String)
(implicit executor:ExecutionContext = defaultEc)
: Future[String] = Future {
println("thread: " + Thread.currentThread().getName)
TimeUnit.SECONDS.sleep(Random.nextInt(3))
s"$beans"
}
}
class FutureTest {
//prints thread: pool-1-thread-1
@Test …Run Code Online (Sandbox Code Playgroud) 程序的许多方法作为参数接收List [Map [String,String]].
我想通过定义一个类来形式化它并使其更具可读性,例如:
class MyClass extends List[Map[String, String]]
Run Code Online (Sandbox Code Playgroud)
但是它会抛出一个错误:
Illegal inheritance from sealed class 'List'
Run Code Online (Sandbox Code Playgroud)
有没有正确的方法来处理它?
我有一个带隐式类的对象:
object ModelUtils {
implicit class RichString(str: String) {
def isNullOrEmpty(x: String): Boolean = x == null || x.trim.isEmpty
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用它时,IntelliJ找不到isNullOrEmpty方法:
"TestString".isNullOrEmpty
Run Code Online (Sandbox Code Playgroud)
我尝试了各种导入导入方法无济于事.我错过了什么?