Scala基于Option变量分配值

huangapple go评论54阅读模式
英文:

scala assign value based on Option variable

问题

Here's the translated code part:

新手学习 ScalaOption

我有 var1`var1: Option[Boolean] = None`

我有 var2`val var2: String = "test"`

如果 var1 为 false我想让 var2 变为空字符串否则保持当前值

类似于 Python

if var1 == false:
   var2 = ""  #(None)
else:
   var2 = "test"  #(或当前值)
英文:

New to scala and Option

I have var1 as var1: Option[Boolean] = None

I have var2 as val var2: Value = Value(name = "test")

I want to have var2 to "" if var1 is false or keep current value.

Someting like? val var3 = var2 if var1==true else ""

similar to python

if var1 == false:
   var2 = None          #(or "")
else:
   var2 = "test"         #(or current value)

答案1

得分: 5

看起来你正在尝试在 Scala 中使用类似于在 Python 中的方式。不确定你具体想要解决什么问题。根据你在问题中提供的细节,你可以以不同的方式解决问题:

使用 Option 类的方法:

val value1         = Option(someBooleanProvided)
val valueFiltered  = value1.filter(val1 => val1) // 这也可以写成 `.filter(identity)`
val valueMapped    = valueFiltered.map(_ => someStringValueProvided)
val valueUnwrapped = valueFilteredAndMapped.getOrElse(emptyString)

逐行解释一下发生了什么:

  • Option.filter:如果值是 true,你将得到相同的 Option,没有变化。如果是 false,你将得到一个 None
  • Option.map:如果 OptionSome,你将得到一个带有 map 中返回的值的新 Option。如果 OptionNone,你将再次得到一个 None
  • Option.getOrElse:如果 OptionSome,你将得到包含在 Option 中的值(在这种情况下是一个 String)。如果值是 None,你将得到 getOrElse 函数中传递的值。

使用 For Comprehensions:

val val2 = for {
  val1 <- Option(someBooleanProvided) if val1 
} yield someStringValueProvided
val valueUnwrapped = val2.getOrElse(emptyString)

如文档中所述,这只是对 flatMapmapwithFilter 的语法糖。在这种情况下,if 与前面示例中的 filter 相同,yield 与我们使用 map 时相同。最后一行是相同的。

使用 Pattern Matching:

val value2 = Option(someBooleanProvided) match {
  case Some(true) => someStringProvided
  case _ => emptyString
}

这类似于 switch case,但你可以检查类型和值。


说到这一点,我建议不要这样做。这篇文章 Baeldung - Scala 中的 Option 类型 可能会帮助你更好地理解如何使用它。Option 类型的理念是对数据缺失进行建模。mapflatMapfilter 等方法不仅仅适用于 Option。它们允许你链式地执行不同的操作,而不必担心值是否存在。一旦我们需要它,我们可以提取值或在没有值的情况下使用默认值。


这些概念来自 函数式编程(不是强制性使用这个范式,但你将无法充分利用 Scala 提供的一些功能)。在 Scala 中经常使用的其中一些是:

  • 不可变值:一旦创建了一个值,它就不能被改变。如果你想更新已经创建的某个东西的值,你必须用新值创建一个新实例。在 Scala 中,你可以使用 val 或 var
变量类型 描述
val 创建一个不可变的变量,类似于 Java 中的 final。除非有理由需要可变变量,否则应该始终使用 val 创建变量。
var 创建一个可变的变量,只有在变量的内容会随时间变化时才应该使用它。
  • 高阶函数:我们可以说这是一种特定的多态性。与其有一个父类和每个子类都对每个方法有不同的实现,你可以将一个函数作为参数传递。

我还建议查看以下链接:

英文:

Looks like you are trying to use Scala as if you still in Python. Not sure what exactly are you trying to solve here. Based on the details you gave in the question, you can solve your problem in different ways:

Using methods from Option class:

val value1         = Option(someBooleanProvided)
val valueFiltered  = value1.filter(val1 => val1) // this could also be written as `.filter(identity)`
val valueMapped    = valueFiltered.map(_ => someStringValueProvided)
val valueUnwrapped = valueFilteredAndMapped.getOrElse(emptyString)

Lets explain line by line what is happening:

  • Option.filter: if the value is true, you will get the some Option with no changes. If it is false, you will get a None
  • Option.map: if the Option is a Some, you will get a new Option with the value returned inside map. If the Option is a None, you will get a None again.
  • Option.getOrElse: if the Option is a Some you will get the value contained inside the Option (an String in this case). If the value is a None, you will get the value passed inside the function getOrElse.

Using For Comprehensions:

val val2 = for {
  val1 <- Option(someBooleanProvided) if val1 
} yield someStringValueProvided
val valueUnwrapped = val2.getOrElse(emptyString)

As it explained in the docs, this is just a syntax sugar for flatMap, map and withFilter. In this case the if is the same as filter in the previous example, the yield is the same as when we used map. The last line is the same.

Using Pattern Matching:

val value2 = Option(someBooleanProvided) match {
  case Some(true) => someStringProvided
  case _ => emptyString
}

This is similar to a switch case, but you can check types and values.


That being said, I suggest to not do that. The article Baeldung - The Option Type in Scala might help you to understand a bit more how to use it. The idea of the Option type, is to model the absence of data. The methods map, flatMap, filter and some others are not exclusive from Option. Those ones, lets you chain different operations without being worried about if the value is present or not. Once we need it, we can extract the value or use a default value in case there is no value.


These concepts comes from functional programming (it's not mandatory to use this paradigm, but you will not be taking advantage of some features that scala offers). A couple of them that are frequently used in Scala are:

  • Immutable values: once a value is created, it can be changed. If you want to update a value of something that it was already created, you have to create a new instance with the new value.
    In Scala you can use val or var.
Variable type Description
val Creates an immutable variable—like final in Java. You should always create a variable with val, unless there’s a reason you need a mutable variable.
var Creates a mutable variable, and should only be used when a variable’s contents will change over time.
  • Higher order functions: we could say that is an ad-hoc polymorphism. Instead of having a parent class with a child classes and each one has a different implementation for each method, you can pass a function as an argument.

I will also suggest to check the following links

huangapple
  • 本文由 发表于 2023年6月13日 00:32:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76458622.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定