如何将String方法作为可调用参数传递?

时间:2019-01-21 10:15:21

标签: scala

假设我有一个类似的功能:

  private def throwUnlessValid[T](func: (String => T)): T = {
    try {
      func()
    } catch {
      case _: Throwable => throw new Error(s"""string: "${s}" is not a numeric""")
    }
  }

我想这样称呼它:

  implicit val intParser: TryParser[Int] = (s: String) => {
    s.trim.isEmpty match {
      case true => 0
      case false => throwUnlessValid[Int](s.toInt)
    }
  }

这将由于s.toInt(即Int)的结果而失败。即使我想传递可调用函数以在其他方法中调用。

我该如何实现?

4 个答案:

答案 0 :(得分:3)

语法为_.toInt,这是s => s.toInt的简写(或没有类型推断的(s: String) => s.toInt)。通常,请搜索“ scala lambdas”以获取更多有关此的信息。

但是问题是您在调用func()时没有传递字符串。 s中还有throw new Error(s"""string: "${s}" is not a numeric""");如果s在您的范围内,则应改为func(s)。也许你想要

private def throwUnlessValid[T](func: () => T): T = { ... }

throwUnlessValid(() => s.toInt)

使用by-name parameters,您甚至可以编写

private def throwUnlessValid[T](func: => T): T = { ... }

throwUnlessValid(s.toInt)

答案 1 :(得分:2)

您可以使用_.toInt传递可调用函数,x => x.toInt是函数throwUnlessValid的简写。

但这不能解决问题,因为您的String函数不起作用,有两个原因:

  1. 您不会为func赋予s参数
  2. 您尝试打印此功能不可见的s

您有两种选择:

  1. throwUnlessValid传递给func,并将其传递给func
  2. => T设置为s参数,并从Error字符串中删除对var Numbers = [1,2,3,4,5,6,7] console.log(Numbers.includes(1)) // True 的引用。

答案 2 :(得分:1)

您需要修复throwUnlessValid函数。 当前,它接受以字符串为参数的函数作为参数:

throwUnlessValid[T](func: (String => T))

但是,您尝试不带任何参数调用它:func()显然不起作用。除此之外,您还引用了不存在的变量s:${s},它也会产生错误。

为了修复throwUnlessValid函数,您可以将toInt作为副参数传递:

private def throwUnlessValid[T](code: => T): T = {
    try {
      code
    } catch {
      case ex: Throwable => throw new Error(s"""string: "${ex.getMessage}" is not a numeric""")
    }
  }

换句话说,您不需要更改现有的intParser实现(包括throwUnlessValid[Int](s.toInt)调用),只需要更改throwUnlessValid的实现即可。

答案 3 :(得分:0)

如果我的理解不正确,那么您正在寻找。

实际上,问题在于您没有将字符串传递给函数(func),因此它不起作用。

import scala.util.{Failure, Success, Try}

object Solution1 extends App {
  private def throwUnlessValid[T](func: (String => T)): T = {
    Try {
      func("1")
    } match {
      case Success(_) => //do Something which return T

      case Failure(ex) => throw new Error(s"""string: "${ex}" is not a numeric""")
    }
  }

  implicit val intParser: String => Int = (s: String) => {
    if (s.trim.isEmpty) {
      0
    } else {
      throwUnlessValid[Int](_ => s.toInt)
    }
  }
}