Scala:隐式排序问题

时间:2016-02-02 04:51:52

标签: scala implicit-conversion scalatest

我正在从书Learning Scala开始练习,一个问题是:

  

隐式参数的常用用法是默认设置   大部分时间都有效,但在特殊情况下可能会被覆盖。假设   你正在编写一个排序函数,它采用文本行和   行可以以右对齐的数字开头。如果要使用排序   数字,可能以空格为前缀,你将如何编码   隐含参数中的这种能力?你会如何允许用户   覆盖此行为并忽略排序的数字?

我的解决方案:

def sortLines(l: List[String])(implicit o: Ordering[String]) = l.sorted

使用Scala测试进行单元测试:

"Ch10" should "order lines starting with right-aligned numbers" in {
    val l = List(" 2 a", " 1 b", " 3 c")

    implicit val orderingByNumber: Ordering[String] = Ordering.by(_.trim.split("\\s")(0).toInt)
    val orderingIgnoringNumber: Ordering[String] = Ordering.by(_.trim.split("\\s")(1))

    Ch10.sortLines(l) should contain inOrder(" 1 b", " 2 a", " 3 c")

    Ch10.sortLines(l)(orderingIgnoringNumber) should contain inOrder(" 2 a", " 1 b", " 3 c")
}

问题是测试失败,java.lang.NumberFormatException: For input string: "b"。为什么呢?

1 个答案:

答案 0 :(得分:2)

Ordering.by具有以下签名:

def by[T, S](f: T => S)(implicit ord: Ordering[S]): Ordering[T]

函数结果类型采用隐式Ordering,在您的情况下为String。此时定义的隐式Ordering[String]orderingByNumber。所以会发生orderingIgnoringNumber切断字符串中的第二个单词,并尝试使用orderingByNumber对它们进行排序,然后Int会尝试将它们转换为orderingIgnoringNumber,并抛出异常。< / p>

您可以针对val orderingIgnoringNumber: Ordering[String] = Ordering.by((_: String).trim.split("\\s")(1))(Ordering.String) 尝试此实施:

Ordering[String]

这明确使用原始your_theme > default > template > catalog > product > view > addto.phtml <?php if ($this->helper('wishlist')->isAllow()) : ?> <a href="<?php echo $_wishlistSubmitUrl ?>" onclick="productAddToCartForm.submitLight(this, this.href); return false;" class="link-wishlist"> <?php echo $this->__('Add to Wishlist') ?> </a> <?php endif; ?>