Scala:简洁的方式来表达以下构造

时间:2010-07-22 07:34:17

标签: scala

我会给出一些C风格的“括号”伪代码来表示我想以另一种方式表达的内容:

for (int i = 0; i < n; i++) {
    if (i == 3 || i == 5 || i == 982) {
        assertTrue( isCromulent(i) );      
    } else {
        assertFalse( isCromulent(i) );
    }
}

for 循环不是很重要,这不是我的问题:我想知道如何使用Scala重写循环内部的内容。

我的目标不是让最短的代码成为可能:这是因为我想了解在Scala中可以对方法名称(?)进行何种操作。

你可以在Scala中执行类似下面的操作(以下仍然是某种伪代码,而不是Scala代码):

assert((i==3 || i==5 || i==982)?True:False)(isCromulent(i))

甚至是这样的事情:

assertTrue( ((i==3 || i==5 || i==982) ?  : ! ) isCromulent(i) )

基本上我想知道测试(i == 3 || i == 5 || i == 982)的结果是否可以用于两种方法之间的分派或在表达式之前添加“not”。

我不知道它是否有意义所以请善待(看看我的个人资料):)

4 个答案:

答案 0 :(得分:10)

虽然在这种情况下,pelotom的解决方案要好得多,但您也可以这样做(这比您最初的要求更接近):

(if (i==3||i==5||i==982) assertTrue else assertFalse)(isCromulent(i))

动态构造名称可以通过反射来完成,但这肯定不会简洁。

答案 1 :(得分:8)

assertTrue(isCromulent(i) == (i==3||i==5||i==982))

答案 2 :(得分:6)

在Scala类型系统中,无法根据条件动态创建方法名称。

但在这种情况下根本不需要。

val condition = i == 3 || i == 5 || i == 982
assertEquals(condition, isCromulent(i))

答案 3 :(得分:2)

我希望没有人会介意这种反应,这是一个旁边而不是直接的答案。

我发现问题和答案到目前为止非常有趣,并花了一段时间寻找基于模式匹配的替代方案。

以下是尝试概括这个(非常具体的)测试类别:

class MatchSet(s: Set[Int]) {def unapply(i: Int) = s.contains(i)}
object MatchSet {def apply(s: Int*) = new MatchSet(Set(s:_*))}


val cromulentSet = MatchSet(3, 5, 982)

0 until n foreach {
  case i @ cromulentSet() => assertTrue(isCromulent(i))
  case i                  => assertFalse(isCromulent(i))
}

我们的想法是创建MatchSet实例中包含的值范围,而不是使用显式匹配。