根据Scala Spec(2.8),对于要发现的隐式,它必须在本地范围,继承范围或伴随对象中定义.鉴于此,在我看来,下面的代码应该没有明确导入伴随对象的内容.我在Scala库源中看到了这个(例如CanBuildFrom).似乎我应该能够从XX类的定义之外调用XX.foo()并使用我所使用的伴随类中的隐式参数.我错过了什么?
object XX {
implicit def XYZ[T]: (T) => Unit = null
}
class XX {
// import XX._ // Works with this line uncommented...
def foo(s: String)(implicit f: (String) => Unit): Unit = {
if (f == null)
println("Just: " + s)
else
f(s)
}
def bar {
foo("abc"){ s => println("Func: " + s)}
foo("xyz") // <-- Compile error here: could not find implicit value for parameter f
}
}
Run Code Online (Sandbox Code Playgroud) 在我非常简单的布尔表达玩具程序中,我有以下评估函数:
eval' :: Expr -> M.Map Char Bool -> Bool
eval' (Const c) values = c
eval' (Var v) values = M.findWithDefault False v values
eval' (Not x) values = not (eval' x values)
eval' (And a b) values = eval' a values && eval' b values
eval' (Or a b) values = eval' a values || eval' b values
eval' (Xor a b) values = eval' a values /= eval' b values
Run Code Online (Sandbox Code Playgroud)
我想知道是否有办法values隐含地传递表格?也许在Monads的帮助下?
根据Scaladoc,没有map在Array类中命名的方法,但是在中implicit def intArrayOps (xs: Array[Int]): ArrayOps[Int]定义了一个隐式函数scala.Predef.所以,你可以申请map上Array(1,2,3,4),如果你喜欢.但我感到困惑的是,map结果是类型Array[Int],而不是ArrayOps[Int].这是我的测试:
scala> val array = Array(1,2,3,4)
array: Array[Int] = Array(1, 2, 3, 4)
scala> array.map(x => x)
res18: Array[Int] = Array(1, 2, 3, 4)
scala> res18.isInstanceOf[Array[Int]]
res19: Boolean = true
scala> res18.isInstanceOf[scala.collection.mutable.ArrayOps[Int]]
warning: there wre 1 unchecked warnings; re-run with -unchecked for details
res20: Boolean = false
Run Code Online (Sandbox Code Playgroud) 大家好 请原谅我在Scala上提出一个愚蠢的问题.虽然我已经在Scala中编程了大约2年,但我仍然觉得很难理解其implicit用法.我们来举一个讨论的例子:
Array(1,2,3,4).map(x => x)
Run Code Online (Sandbox Code Playgroud)
如果你查看scaladoc,你就无法map在Array课堂上找到这个方法.map可以应用的原因是在Array(1,2,3,4)中implicit def intArrayOps (xs: Array[Int]): ArrayOps[Int]定义了隐式函数scala.Predef.
但是,有两个参数列表,第二个参数列表写为implicit bf: CanBuildFrom[Array[T], B, That]).现在我不知道该编译器发现一个适当的参数类型CanBuildFrom申请时map上Array(1,2,3,4).
考虑使用Scala中的以下代码:
object Test {
class A {}
class B extends A {}
class AI extends A {
def sayHello: String = "Hello from AI"
}
implicit def AtoAI(a: A): AI = a
class BI extends B {
def sayHello: String = "Hello from BI"
}
implicit def BtoBI(b: B): BI = b
def main(args: Array[String]) {
val a = new A
println(a.sayHello)
val b = new B
println(b.sayHello)
}
}
Run Code Online (Sandbox Code Playgroud)
使用implicits会导致循环代码.事实上,反汇编表明,生成的转换方法只有一个goto 0内部:
public Test$AI AtoAI(Test$A);
Code:
0: goto …Run Code Online (Sandbox Code Playgroud) 我有一个方法,有很多隐含的参数:
def hello(message:String)(implicit a:A,b:B,c:C, ..., user: User) = {...}
Run Code Online (Sandbox Code Playgroud)
现在考虑这样一个类:
object Users extends Controller {
implicit a: A = ...
implicit b: B = ...
...
def index(id:String) = Action {
User.findById(id) match {
case Some(user) => {
implicit val _user = user
hello("implicit")
}
case _ => BadRequest
}
}
}
Run Code Online (Sandbox Code Playgroud)
你可以在上面的例子中看到这一行:
implicit val _user = user
Run Code Online (Sandbox Code Playgroud)
它的存在只是为了使对象user成为一个隐式对象.否则,我必须打电话给hello:
hello("implicit")(a,b,c,... user)
Run Code Online (Sandbox Code Playgroud)
我在想是否有任何改进代码的方法,例如我们不需要定义那个_user变量但是user隐含它.
我们运行Spring 3.1/Hibernate 4/Java 7/Tomcat 7/MSSQL 2008 R2 Web应用程序.我们必须处理遗留数据和归档数据.从存档中提取数据时,我们需要使用原始唯一标识符,以便其他(非存档)记录能够正确地重新水合.这些标识符存储在主键/自动增量字段中.
在此之前,现在,当我们在使用Spring 3.0/3.5休眠,下面的代码工作中插入一个提取的记录回其相应的表(我们已经有变量session,entity以及fullTableName在范围内):
session.doWork( new Work()
{
@Override
public void execute(Connection connection) throws SQLException
{
PreparedStatement statement = null;
try
{
statement = connection.prepareStatement(String.format("SET IDENTITY_INSERT %s ON", fullTableName));
statement.execute();
session.save(entity);
statement = connection.prepareStatement(String.format("SET IDENTITY_INSERT %s OFF", fullTableName));
statement.execute();
}
finally
{ /* close the statement */ }
}
});
Run Code Online (Sandbox Code Playgroud)
就像我提到的,这在Hibernate 3.5中运行良好,但是现在我们已经升级到Hibernate 4,它已经停止工作了.Work和IsolatedWork之间有什么区别吗?
为了解决问题,并避免任何Work接口问题,我们尝试了以下方法:
session.createSQLQuery(String.format("SET IDENTITY_INSERT %s ON", fullTableName)).executeUpdate();
session.save(entity);
session.createSQLQuery(String.format("SET IDENTITY_INSERT %s OFF", fullTableName)).executeUpdate();
Run Code Online (Sandbox Code Playgroud)
但是,这也不起作用.具体来说,抛出的异常是java.sql.SQLException: Cannot …
我想有一个更高阶的函数,它接受一个接受特定隐式参数的函数的参数.
更确切地说,我正在尝试创建一个函数,该函数采用Future依赖于隐式上下文的创建方法,并返回不依赖于上下文的方法.
更具体地说,让我说我有这样的事情:
def foo(a: Int)(implicit ctx: ExecutionContext): Future[Float] = future { somelongBar... }
Run Code Online (Sandbox Code Playgroud)
我想有一个像这样的方法:
def provideCtx[A](func: ExecutionContext => A): A = {
val ctx = setupCtx
func(ctx)
}
Run Code Online (Sandbox Code Playgroud)
但如果我调用provideCtx(foo),编译器会抱怨缺少隐式执行上下文.
我正在处理ExecutionContext的事实并不是很重要.我想要找到的是如何编写参数类型以接受具有特定类型的隐式参数的函数.我理解隐式部分是一个curryed参数,所以实际上我有一个像这样的函数:ExecutionContext => Int => Future[Float],我很确定在运行时,jvm不知道ExecutionContext是隐式的,但我不能使编译器明白了.
这是一个简单的重现器,我在其中定义了一个带有隐式重新排序转换的"可交换"对类型.如果函数的参数f位于预先存在的命名值(t在示例中),则编译器会按预期应用隐式转换.但是,如果我尝试f直接调用literal CommutativePair,它会因类型错误而失败.在这种情况下,编译器不应用隐式重新排序转换.
object repro {
import scala.language.implicitConversions
case class CommutativePair[A, B](a: A, b: B)
object CommutativePair {
// Support a kind of commutative behavior via an implicit reordering
implicit def reorderPair[B, A](pair: CommutativePair[B, A]) =
CommutativePair(pair.b, pair.a)
}
// The idea is to allow a call to 'f' with Pair[Int, String] as well,
// via implicit reorder.
def f(p: CommutativePair[String, Int]) = p.toString
val t = CommutativePair(3, "c")
// This works: the implicit …Run Code Online (Sandbox Code Playgroud) 我是Scala的新手,并且一直在努力学习和理解隐式转换和参数,并遇到了一个令我感到困惑的场景.
对于上下文,我使用Scaldi在Akka应用程序中执行依赖注入,并希望有多个可注入的actor从抽象类继承.我相信我无法使抽象类成为一个特征,因为我们需要Injector通过构造函数参数使隐式可用来利用框架.
展示我所看到的行为的一个非常人为的例子如下:
class SecretSauce {}
abstract class Base(implicit secretSauce: SecretSauce) {}
class Concrete extends Base {}
object Example extends App {
... // Setup Actor system, etc, etc
implicit val secretSauce: SecretSauce = new SecretSauce()
}
Run Code Online (Sandbox Code Playgroud)
我期待一些工作,但我得到一个编译错误:
Unspecified value parameter secretSauce.
class Concrete extends Base {
^
Run Code Online (Sandbox Code Playgroud)
如果我将隐式参数添加到具体类中,就像这样,事情可行:
class Concrete(implicit secretSauce: SecretSauce) extends Base {}
Run Code Online (Sandbox Code Playgroud)
我认为我的困惑源于隐式参数如何工作 - 在我所描述的情况下,它们是不是由子类继承的?有人可以ELI5在我的例子中发生了什么或指向我可以帮助清理的参考?
谢谢!