在单行中缓存中间变量

时间:2013-04-11 18:55:10

标签: scala

我可以以某种方式将i.toString缓存在这个简单的函数定义中吗?

def palindrome(i: Int) = i.toString == i.toString.reverse

我希望保持这个功能简单,没有经典的多线,支撑功能..

6 个答案:

答案 0 :(得分:6)

你可以这样做:

def palindrome(i: Int) = ((s:String) => s == s.reverse)(i.toString)

答案 1 :(得分:6)

嗯,Scala没有像一些传统函数式语言那样的let语句,但这主要是因为val + braces实现了同样的目的。您是否反对多线部分或一般支撑?因为它很难被击败:

def palindrome(i: Int) = { val s = i.toString; s == s.reverse }

试图忽视大括号可能只会推动人物数量增加。

答案 2 :(得分:5)

使用正向管道运算符:

scala> implicit class PipedObject[A](value: A) {
     |   def |>[B](f: A => B): B = f(value)
     | }
defined class PipedObject

scala> def palindrome(i: Int) = i.toString |> (s => s == s.reverse)
palindrome: (i: Int)Boolean

虽然这可以优雅地解决您的问题,但我建议将palindrome的签名从palindrome(Int)更改为palindrome(String)并将其与palindrome(i.toString)一起调用(并将其重命名为{{1} }})。

答案 3 :(得分:3)

这是一个单行,但是括号仍在这里。但对我来说似乎更短:

def palindrome(i: Int) = { val s = i.toString; s == s.reverse }

如果你有很多这样的功能,你也可以这样做:

@inline def let[T, R](expr: =>T)(body: T => R): R = body(expr)

def palindrome(i: Int) = let(i.toString) { s => s == s.reverse }

答案 4 :(得分:0)

需要经常两次引用某些内容,以便将其丰富到方法中是有用的:

implicit class DiamondMapper[A](val a: A) extends AnyVal {
  def diamond[B](f: (A,A) => B) = f(a,a)
}

然后:

scala> 575.toString.diamond(_ == _.reverse)
res1: Boolean = true

这是管道操作符(|>的特殊情况,如果你喜欢符号表示法),但这是一个很常见的用例,你可能想要创建自己的用例。

(Diamond这里因为它需要一个值,将它分成两部分,然后再将它合并在一起。)

答案 5 :(得分:0)

Scala 2.13开始,标准库提供了链接操作pipe,该链接操作可用于转换/管道i.toString并具有检查字符串是否是回文的功能:

import scala.util.chaining._

def palindrome(i: Int) = i.toString.pipe(s => s == s.reverse)