(Scala) 我是否正确使用了选项? [英] (Scala) Am I using Options correctly?

查看:25
本文介绍了(Scala) 我是否正确使用了选项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在研究我的函数式编程 - 我对它相当陌生.我在这里正确使用选项吗?我目前对自己的技能感到非常不安全.我希望我的代码尽可能安全 - 任何人都可以指出我在这里做错了什么还是没有那么糟糕?我的代码在这里非常简单:

I'm currently working on my functional programming - I am fairly new to it. Am i using Options correctly here? I feel pretty insecure on my skills currently. I want my code to be as safe as possible - Can any one point out what am I doing wrong here or is it not that bad? My code is pretty straight forward here:

def main(args: Array[String]): Unit =
  {
    val file = "myFile.txt"
    val myGame = Game(file) //I have my game that returns an Option here

    if(myGame.isDefined) //Check if I indeed past a .txt file
    {
      val solutions = myGame.get.getAllSolutions() //This returns options as well
      if(solutions.isDefined) //Is it possible to solve the puzzle(crossword)
      {
        for(i <- solutions.get){ //print all solutions to the crossword
          i.solvedCrossword foreach println
        }
      }
    }
  }

-谢谢!!^^

推荐答案

根据经验,您可以将 Option 视为 Java 空指针的替代品.也就是说,如果您可能想在 Java 中使用 null,在 Scala 中使用 Option 通常是有意义的.

As a rule of thumb, you can think of Option as a replacement for Java's null pointer. That is, in cases where you might want to use null in Java, it often makes sense to use Option in Scala.

您的 Game() 函数使用 None 来表示错误.所以你并没有真正使用它作为 null 的替代品(至少我认为等效的 Java 方法在那里返回 null 而不是抛出一个例外),但作为例外的替代品.这不是 Option 的好用法,因为它会丢失错误信息:您无法再区分文件不存在、文件格式错误或其他类型的错误.

Your Game() function uses None to represent errors. So you're not really using it as a replacement for null (at least I'd consider it poor practice for an equivalent Java method to return null there instead of throwing an exception), but as a replacement for exceptions. That's not a good use of Option because it loses error information: you can no longer differentiate between the file not existing, the file being in the wrong format or other types of errors.

相反,您应该使用 Either.Either 由情况 LeftRight 组成,其中 Right 就像 OptionSome,但LeftNone 的不同之处在于它也接受一个参数.在这里,该参数可用于存储有关错误的信息.因此,您可以创建一个包含可能的错误类型的案例类,并将其用作 Left 的参数.或者,如果您从不需要以不同方式处理错误,而只是将它们呈现给用户,您可以使用带有错误消息的字符串作为 Left 的参数,而不是案例类.

Instead you should use Either. Either consists of the cases Left and Right where Right is like Option's Some, but Left differs from None in that it also takes an argument. Here that argument can be used to store information about the error. So you can create a case class containing the possible types of errors and use that as an argument to Left. Or, if you never need to handle the errors differently, but just present them to the user, you can use a string with the error message as the argument to Left instead of case classes.

getAllSolutions 中,您只是使用None 作为空列表的替代.这是不必要的,因为空列表不需要替换.当没有解决方案时,只返回一个空列表是完全没问题的.

In getAllSolutions you're just using None as a replacement for the empty list. That's unnecessary because the empty list needs no replacement. It's perfectly fine to just return an empty list when there are no solutions.

当涉及到与 Option 的交互时,您使用的是 isDefined + get,这有点反模式.get 可以用作快捷方式,如果您知道您拥有的选项从不None,但通常应避免使用.isDefined 一般只用于需要知道选项是否包含值,但不需要知道值的情况.

When it comes to interacting with the Options, you're using isDefined + get, which is a bit of an anti pattern. get can be used as a shortcut if you know that the option you have is never None, but should generally be avoided. isDefined should generally only be used in situations where you need to know whether an option contains a value, but don't need to know the value.

如果您需要知道是否有值以及该值是什么,您应该使用模式匹配或 Option 的高阶函数之一,例如 mapflatMapgetOrElse(如果你眯着眼睛考虑按名称参数,这是一种高阶函数职能).如果您想对存在的值执行某些操作,否则什么都不做,您可以使用 foreach(或等效的 for 循环),但请注意在这里的错误情况下真的不应该做任何事情.您应该将错误告诉用户.

In cases where you need to know both whether there is a value and what that value is, you should either use pattern matching or one of Option's higher-order functions, such as map, flatMap, getOrElse (which is kind of a higher-order function if you squint a bit and consider by-name arguments as kind-of like functions). For cases where you want to do something with the value if there is one and do nothing otherwise, you can use foreach (or equivalently a for loop), but note that you really shouldn't do nothing in the error case here. You should tell the user about the error instead.

这篇关于(Scala) 我是否正确使用了选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆