代码之家  ›  专栏  ›  技术社区  ›  NoozNooz42

Scala:表示以下构造的简洁方法

  •  4
  • NoozNooz42  · 技术社区  · 14 年前

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

    这个 对于 循环不是很重要,这不是我问题的重点:我想知道如何使用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 回复  |  直到 14 年前
        1
  •  10
  •   Alexey Romanov    14 年前

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

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

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

        2
  •  8
  •   Tom Crockett    14 年前
    assertTrue(isCromulent(i) == (i==3||i==5||i==982))
    
        3
  •  6
  •   retronym    14 年前

    在Scala类型系统中,不可能基于条件动态创建方法名。

    但在这种情况下根本没有必要。

    val condition = i == 3 || i == 5 || i == 982
    assertEquals(condition, isCromulent(i))
    
        4
  •  2
  •   Don Mackenzie    14 年前

    我希望没有人介意这个回答,这是一个旁白,而不是一个直接的回答。

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

    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))
    }
    

    其思想是创建匹配集实例中包含的值的范围,而不是使用显式匹配。