Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在flatmapping AnyRef之后,Scala无法解析正确的重载SLF4J方法*_Scala_Slf4j_Scala Java Interop - Fatal编程技术网

在flatmapping AnyRef之后,Scala无法解析正确的重载SLF4J方法*

在flatmapping AnyRef之后,Scala无法解析正确的重载SLF4J方法*,scala,slf4j,scala-java-interop,Scala,Slf4j,Scala Java Interop,我有一个如下所示的Java接口: 接口Bazz{ 空栏(字符串消息、对象参数…); } 我想实现该接口(恰好在Scala中),并使用SLF4J日志记录args参数(为了解决这个问题,使用另一个Scala日志库不是一个选项) 以及以下(人为)scala代码: 对象Foo扩展Bazz{ private val log=LoggerFactory.getLogger(Main.getClass) 定义栏(参数:AnyRef*){ info(“处理参数:{},{},{},{}”,参数:*) //…用a

我有一个如下所示的Java接口:

接口Bazz{
空栏(字符串消息、对象参数…);
}
我想实现该接口(恰好在Scala中),并使用SLF4J日志记录
args
参数(为了解决这个问题,使用另一个Scala日志库不是一个选项)

以及以下(人为)scala代码:

对象Foo扩展Bazz{
private val log=LoggerFactory.getLogger(Main.getClass)
定义栏(参数:AnyRef*){
info(“处理参数:{},{},{},{}”,参数:*)
//…用args做一些事情。。。
}
}
对象主应用程序{
val arr:Seq[String]=数组(“A”、“B”、“C”)
val anyRef:anyRef=arr
食品酒吧(arr)
}
}

运行
Main
,我得到以下输出:

22:49:54.658 [run-main-0] INFO: sample.Main$ Processing params: WrappedArray(A, B, C), {}, {} 
这不好,因为
:*
正在分解args,但第一个元素是数组。出于不在这里讨论的原因,我实际上需要将该数组的元素作为单个
Object[]
参数传递给SLF4J的
Logger.info(String,Object[])
方法

这是我的第一次尝试:

def bar(args: AnyRef*) {
  val flatArgs = args.flatMap {
    case s: Seq[_] => s
    case x         => Seq(x)
  }
  log.info("Processing params: {}, {}, {}", flatArgs: _*)
  // ... do stuff with args...
}
这不会编译为以下错误:

[error] Main.scala:18: overloaded method value info with alternatives:
[error]   (x$1: org.slf4j.Marker,x$2: String,x$3: <repeated...>[Object])Unit <and>
[error]   (x$1: org.slf4j.Marker,x$2: String)Unit <and>
[error]   (x$1: String,x$2: Throwable)Unit <and>
[error]   (x$1: String,x$2: <repeated...>[Object])Unit <and>
[error]   (x$1: String,x$2: Any)Unit
[error]  cannot be applied to (String, Any)
[error]     log.info("Processing params: {}, {}, {}", flatArgs: _*)
[error]         ^
[error] one error found
[error]Main.scala:18:重载的方法值信息和可选项:
[错误](x$1:org.slf4j.Marker,x$2:String,x$3:[对象])单位
[错误](x$1:org.slf4j.Marker,x$2:String)单位
[错误](x$1:String,x$2:Throwable)单位
[错误](x$1:String,x$2:[对象])单位
[错误](x$1:String,x$2:Any)单位
[错误]无法应用于(字符串,任意)
[error]log.info(“处理参数:{},{},{},{}”,flatArgs:*)
[错误]^
[错误]发现一个错误

如何更改此代码以使其编译并打印
处理参数:A、B、C

这里的问题是
Int
AnyVal
,这意味着它不是
AnyRef/Object
另外,
数组
不是可遍历的
数组

现在在
foo
方法中,我们对varargs进行模式匹配

def foo(msg:String,varargs:AnyRef*) { varargs.toList match {
  case (h:TraversableOnce[_]) :: Nil => log.info(msg, h.toSeq.asInstanceOf[Seq[AnyRef]]:_*)
  case (h:Array[_]) :: Nil => log.info(msg, h.toSeq.asInstanceOf[Seq[AnyRef]]:_*)
  case _ => log.info(msg,varargs:_*)
}}
我们处理的案例有3个:

case (h:TraversableOnce[_]) :: Nil => log.info(msg, h.toSeq.asInstanceOf[Seq[AnyRef]]:_*)
TraversableOnce
是Scala集合的基本特征之一;我所知道的每个集合都扩展了它(
Array
不是集合,它不扩展它)。它可以包含
AnyVal
AnyRef
,但运行时的实际项将被包装为原语(java.lang.Integer等)。所以我们可以在这里从
Seq[Any]
向下转换到
Seq[AnyRef]
,我们应该没事了

case (h:Array[_]) :: Nil => log.info(msg, h.toSeq.asInstanceOf[Seq[AnyRef]]:_*)
就像我们对
TraversableOnce
所做的那样,将其转换为
Seq
,然后向下转换。到
Seq
的转换将为我们包装任何原语

case _ => log.info(msg,varargs:_*)

一般情况下,
varargs
可以为空,或包含多个条目。

ggovan的更简单变体,在调用
foo
之前进行匹配:

val arr: Seq[Int] = Array(1,2,3)
val anyRef: AnyRef = arr 

val msg = "Another message: {}, {}, {}"
  anyRef match {
    case seq: Seq[_] => foo(msg, seq.asInstanceOf[Seq[AnyRef]]: _*)
    case x => foo(msg, x)
  }    

这是我重新陈述(现在很明显)的问题的答案。抱歉之前没有明确的问题:

def条(args:AnyRef*){
val flatArgs=args.flatMap{
案例s:Seq[\u]=>s
案例x=>序号(x)
}.toArray.asInstanceOf[Array[Object]]
info(“处理参数:{},{},{},{}”,flatArgs:*)
}
注意:如果没有[Array[Object]]
的安装,则会发生以下情况:

[error] type mismatch;
[error]  found   : Array[Any]
[error]  required: Array[Object]
[error] Note: Any >: Object, but class Array is invariant in type T.
[error] You may wish to investigate a wildcard type such as `_ >: Object`. (SLS 3.2.10)
[error]   }.toArray
[error]     ^
[error] one error found

为什么要使用
AnyRef
?修改我的问题以澄清这一点。这是关于java互操作的。听起来可能很糟糕,但您可能能够通过模式匹配参数?也就是说,
案例x:WrappedArray[\u]=>东西
我同意@Ven<代码>anyRef:anyRef是这里的问题
args
是一个单元素数组,其中第一个元素是
WrappedArray
。使用
foo(“message”,arr:*)
来获得所需的行为。我一直使用AnyRef*,因为这就是使用VarArgs实现Java接口的方式。抱歉…重新编写了我的问题。请再读一遍。