Scala:如果在匹配案例中

时间:2017-05-28 15:46:49

标签: scala if-statement functional-programming

有没有办法在scala中将if放入匹配案例?

这样的事情:

def createSchedules(listTask: List[TaskOrder], physicalResources: List[Physical], humanResources: List[Human], previousTime: Duration): List[TaskSchedule] = listTask match {
    case TaskOrder(id, time, physicalRes, order) :: t =>
      val taskScheduleHumanResources = setHumanResources(physicalRes, humanResources)
      if (physicalRes != null) 
        new TaskSchedule(
          order, 
          order.getProduct(), 
          Task(id, time, physicalRes), 
          physicalRes, 
          taskScheduleHumanResources, 
          order.quantity, 
          previousTime, 
          previousTime + time) :: createSchedules(t, physicalRes, humanResources, previousTime + time)
    case Nil => Nil
  }

这样做我收到错误说:

  

类型不匹配; found:需要的单位:List [Objects.TaskSchedule]

最好的方法是什么?

3 个答案:

答案 0 :(得分:2)

编译器推断Unit的原因是您没有else子句,这意味着如果physicalReselse,则不会返回值空。

您需要在代码中添加case TaskOrder(id, time, physicalRes, order) :: t => val taskScheduleHumanResources = setHumanResources(physicalRes, humanResources) if (physicalRes != null) // stuff else createSchedules(t, physicalRes, humanResources, previousTime + time) 子句:

physicalRes

您还可以折叠整个集合,只有在找到非空val res: List[TaskSchedule] = listTask.foldLeft(List.empty[TaskOrder]) { case (acc, order) => if (order.physicalRes != null) { new TaskSchedule(...) :: acc } else acc } 时才会累积:

void Attack(String attackerName, String defenderName, double attackerDmg, double defenderHp){
    System.out.println(attackerName + " attacked " + defenderName + " causing " + attackerDmg +  " damage.");
    defenderHp -= attackerDmg;
    System.out.println(defenderName + " now has " + defenderHp + " HP.");
}

答案 1 :(得分:1)

如果你这样做

    def createSchedules(listTask: List[TaskOrder],
                        physicalResources: List[Physical],
                        humanResources: List[Human],
                        previousTime: Duration): List[TaskSchedule] = listTask match {
      case TaskOrder(id, time, physicalRes, order) :: t =>{
        val taskScheduleHumanResources = setHumanResources(physicalRes, humanResources);
        if(physicalRes != null) 
          new TaskSchedule(order, order.getProduct(), Task(id, time, physicalRes), physicalRes, taskScheduleHumanResources, order.quantity, previousTime, previousTime + time):: createSchedules(t, physicalRes, humanResources, previousTime + time)
        else 
          Nil
      }
      case Nil => Nil
    }
  }

应该有效

答案 2 :(得分:0)

正如其他人所指出的,编译器会尝试推断if表达式的类型(它会尝试找到ifelse共享的第一个常见超类型。鉴于缺少else,它与Unit一致,因此您收到错误。

如果我理解你要做什么,collect似乎是实现这一目标的最简单方法:

def createSchedules(listTask: List[TaskOrder], physicalResources: List[Physical], humanResources: List[Human], previousTime: Duration): List[TaskSchedule] =
  listTask.collect {
    case TaskOrder(id, time, physicalRes, order) if physicalRes != null =>
      val taskScheduleHumanResources = setHumanResources(physicalRes, humanResources)
      new TaskSchedule(
        order, 
        order.getProduct(), 
        Task(id, time, physicalRes), 
        physicalRes, 
        taskScheduleHumanResources, 
        order.quantity, 
        previousTime, 
        previousTime + time
      )
  }