Scala 如何从方法返回可选信息?
一般的问题是,除了计算的实际结果之外,如何从方法返回附加信息。但是我想,这些信息可以被默默地忽略 以Scala 如何从方法返回可选信息?,scala,Scala,一般的问题是,除了计算的实际结果之外,如何从方法返回附加信息。但是我想,这些信息可以被默默地忽略 以Iterator上的方法dropWhile为例。返回的结果是经过变异的迭代器。但有时我可能对丢弃的元素的数量感兴趣 在dropWhile的情况下,可以通过在迭代器中添加索引并计算之后删除的步骤数,从外部生成此信息。但总的来说,这是不可能的 一个简单的解决方案是返回一个包含实际结果和可选信息的元组。但是,无论何时调用该方法,我都需要处理元组——即使我对可选信息不感兴趣 def removeCharW
Iterator
上的方法dropWhile
为例。返回的结果是经过变异的迭代器。但有时我可能对丢弃的元素的数量感兴趣
在dropWhile
的情况下,可以通过在迭代器中添加索引并计算之后删除的步骤数,从外部生成此信息。但总的来说,这是不可能的
一个简单的解决方案是返回一个包含实际结果和可选信息的元组。但是,无论何时调用该方法,我都需要处理元组——即使我对可选信息不感兴趣
def removeCharWithCount(str: String, x: Char): (String, Int) =
(str.replace(x.toString, ""), str.count(x ==))
// alias that drops the additional return information
def removeChar(str: String, x: Char): String =
removeCharWithCount(str, x)._1
所以问题是,是否有聪明的方法收集这些可选信息
可能通过
选项[X=>Unit]
参数调用默认为None
?有更聪明的方法吗?它肯定不是更聪明,但您可以创建一个方法来删除附加信息
def removeCharWithCount(str: String, x: Char): (String, Int) =
(str.replace(x.toString, ""), str.count(x ==))
// alias that drops the additional return information
def removeChar(str: String, x: Char): String =
removeCharWithCount(str, x)._1
这里只有我的两分钱 您可以声明:
case class RichResult[+A, +B](val result: A, val info: B)
隐式转换为A
:
implicit def unwrapRichResult[A, B](richResult: RichResult[A, B]): A = richResult.result
然后:
以下是我的观点(用一个更现实的例子进行了一些编辑):
然后假设您的原始方法(和用例)实现如下:
object Test extends App {
def dropCounterIterator[A](iter: Iterator[A]) = new Iterator[A] {
def hasNext = iter.hasNext
def next() = iter.next()
override def dropWhile(p: (A) => Boolean): Iterator[A] = {
var count = 0
var current: Option[A] = None
while (hasNext && p({current = Some(next()); current.get})) { count += 1 }
current match {
case Some(a) => Iterator.single(a) ++ this
case None => Iterator.empty
}
}
}
val i = dropCounterIterator(Iterator.from(1))
val ii = i.dropWhile(_ < 10)
println(ii.next())
}
对象测试扩展应用程序{
def dropCounterIterator[A](iter:Iterator[A])=新迭代器[A]{
def hasNext=iter.hasNext
def next()=iter.next()
覆盖def dropWhile(p:(A)=>布尔):迭代器[A]={
变量计数=0
var电流:选项[A]=无
而(hasNext&&p({current=Some(next());current.get})){count+=1}
当前匹配{
case Some(a)=>Iterator.single(a)++this
case None=>Iterator.empty
}
}
}
val i=dropCounterIterator(迭代器.from(1))
val ii=i.dropWhile(<10)
println(ii.next())
}
为了提供和访问信息,代码只需稍加修改:
import info.Info // line added
object Test extends App {
def dropCounterIterator[A](iter: Iterator[A]) = new Iterator[A] {
def hasNext = iter.hasNext
def next() = iter.next()
// note overloaded variant because of extra parameter list, not overriden
def dropWhile(p: (A) => Boolean)(implicit info: Info[Int]): Iterator[A] = {
var count = 0
var current: Option[A] = None
while (hasNext && p({current = Some(next()); current.get})) { count += 1 }
info.data = Some(count) // line added here
current match {
case Some(a) => Iterator.single(a) ++ this
case None => Iterator.empty
}
}
}
val i = dropCounterIterator(Iterator.from(1))
val info = implicitly[Info[Int]] // line added here
val ii = i.dropWhile((x: Int) => x < 10)(info) // line modified
println(ii.next())
println(info.data.get) // line added here
}
导入信息。信息//添加行
对象测试扩展应用程序{
def dropCounterIterator[A](iter:Iterator[A])=新迭代器[A]{
def hasNext=iter.hasNext
def next()=iter.next()
//注意:由于额外的参数列表,重载变量,而不是重写
def dropWhile(p:(A)=>Boolean)(隐式信息:信息[Int]):迭代器[A]={
变量计数=0
var电流:选项[A]=无
而(hasNext&&p({current=Some(next());current.get})){count+=1}
info.data=Some(count)//此处添加了一行
当前匹配{
case Some(a)=>Iterator.single(a)++this
case None=>Iterator.empty
}
}
}
val i=dropCounterIterator(迭代器.from(1))
val info=隐式[info[Int]]//此处添加了一行
valii=i.dropWhile((x:Int)=>x<10)(info)//行已修改
println(ii.next())
println(info.data.get)//此处添加了一行
}
请注意,由于某种原因,类型推断受到影响,我必须对传递给
dropWhile
的函数类型进行注释,而dropWhileM
需要使用状态
单子在计算中穿行计数器。对此进行了思考。缺点是,当类型注释无法推断A
时,您需要类型注释。如果要分配给val
并希望从隐式转换中获益,则无论如何都需要类型注释。顺便说一下,您还可以使用类型归属:val res=someMethod:Int
。如果我必须对可选类型进行注释/归因,那就更好了。然后我认为这是我的问题的解决方案。如果你想要一个解决方案,你把额外的信息归咎于,你最好使用,这是更多的信息。
import info.Info // line added
object Test extends App {
def dropCounterIterator[A](iter: Iterator[A]) = new Iterator[A] {
def hasNext = iter.hasNext
def next() = iter.next()
// note overloaded variant because of extra parameter list, not overriden
def dropWhile(p: (A) => Boolean)(implicit info: Info[Int]): Iterator[A] = {
var count = 0
var current: Option[A] = None
while (hasNext && p({current = Some(next()); current.get})) { count += 1 }
info.data = Some(count) // line added here
current match {
case Some(a) => Iterator.single(a) ++ this
case None => Iterator.empty
}
}
}
val i = dropCounterIterator(Iterator.from(1))
val info = implicitly[Info[Int]] // line added here
val ii = i.dropWhile((x: Int) => x < 10)(info) // line modified
println(ii.next())
println(info.data.get) // line added here
}