我有一个类型为Option[String]
的参数。我知道我们可以对其进行映射或折叠,从而得到String
。我想在其他操作中使用String
。
我无法做到这一点。 你们能帮我举个例子吗?
答案 0 :(得分:1)
如果您有Option[String]
,则有两种选择:
String
Option
内进行计算要获取字符串,您可以使用模式匹配:
def printOption(parameter: Option[String]): Unit =
parameter match {
case None => println("there was no string")
case Some(theString) => println("the string was " + theString)
}
或者您可以使用getOrElse
:
def getTheStringOrSmile(parameter: Option[String]): String =
parameter.getOrElse(":)")
要在Option内进行计算,您可以使用高阶函数,例如map
,flatMap
,foreach
,filter
等上。这些之所以称为“高阶函数”,是因为它们是具有参数的函数,这些参数本身就是函数。
例如,让我们看一下foreach
,该函数具有从String
(或Option
中的任何内容)到Unit
的功能。如果选项包含一个值,foreach
将调用该函数。如果该选项不包含值,则不会发生任何事情。所以我们可以这样写:
def printOptionIfPresent1(parameter: Option[String]): Unit =
parameter.foreach(theString => println("the string was " + theString))
语法theString => println("the string was " + theString)
在这里构造一个函数。 theString
是函数的参数,println("the string was " + theString)
是函数的主体。
如果您在theString => ...
语法中苦苦挣扎,也许printOptionIfPresent1
的以下替代实现可以帮助您了解正在发生的事情:
class Helper$123 extends Function[String, Unit] {
def apply(theString: String): Unit =
println("the string was + theString)
}
def printOptionIfPresent2(parameter: Option[String]): Unit =
parameter.foreach(new Helper$123)
当Scala编译器看到printOptionIfPresent1
时,它或多或少将其转换为类似printOptionIfPresent1
的形式,并为您生成正确的Helper$123
类。
如果您希望发生某些事情(这里:打印到控制台),但是不想返回值,那么foreach
方法是很好的。如果要返回值,请改用map
方法。例如,要计算选项内字符串的长度,可以使用:
def optionalLength1(parameter: Option[String]): Option[Int] =
parameter.map(theString => theString.length)
如果参数也是None
,它也会返回None
。如果您只想返回Int
并在参数为0
的情况下使用None
,则可以添加getOrElse
来取出Int
:
def optionalLength2(parameter: Option[String]): Int =
parameter.map(theString => theString.length).getOrElse(0)
希望这为您提供了一个开始,但请确保也探索filter
和flatMap
。
答案 1 :(得分:1)
是的,您可以在scala中的map
上fold
和Option
。为了简单起见,我们假设Option
是专门的List
,其中只有一个条目或没有条目。
要访问内容,我们有很多选择。最简单的方法是使用get
进行检索。但是正如您所说,您想使用map
或fold
。因此,我们需要首先了解这些功能。
让我们从fold
开始。一般来说,fold
有两种:foldLeft
和foldRight
。 foldLeft
将从集合的开头开始执行某项任务,而foldRight
则以相反的顺序执行。无论如何,都有两个参数列表。第一个包含起始值,第二个包含在每个元素上执行的功能。该函数必须使用两个参数累加器,它们将通过迭代和当前元素传递。该函数的结果必须适合下一个迭代累加器。累加器的类型是从起始值推断出来的。折叠操作的结果将始终与起始值相同。
// Adds all numbers in the list
List(1,2,3,4).foldLeft(0)((accumulator, element) => accumulator += element)
>res0: Int = 10
// Same as above method, but shortened with syntactic sugar
List(1,2,3,4).foldLeft(0)(_ + _)
>res1: Int = 10
// will also add all elements, but with an offset of 5
List(1,2,3,4).foldLeft(5)(_ + _)
>res2: Int = 15
现在让我们继续进行map
。此函数遍历所有元素,并使用提供的功能对其进行修改。结果将是相同的集合类型,并以函数结果的类型键入。
// multiplies each element by 2
List(1,2,3,4).map(element => element * 2)
>res0: List[Int] = List(2,4,6,8)
// the same as above, but shortened with syntactic sugar
List(1,2,3,4).map(_ * 2)
>res1: List[Int] = List(2,4,6,8)
如果我们将此知识应用于Option
,则可以按以下方式使用它:
// multiply contents by 2
List(5).map(_ * 2)
>res0: List[Int] = List(10)
Some(5).map(_ * 2)
>res1: Option[Int] = Some(10)
// multiply empty content by 2
val empty: Option[Int] = None // None cannot be typed
empty.map(_ * 2)
>res2: Option[Int] = None
List[Int]().map(_ * 2)
>res3: List[Int] = List()
如您所见,访问map
函数内部的元素很简单。另外,由于NullPointerException
仅对非空集合进行求值,因此您不受map
的保护。
答案 2 :(得分:0)
要从String
获取Option[String]
的值,请使用getOrElse
并指定默认值,以防Option
为None
:
val str = strOption.getOrElse("default")
如果您想先进行一些处理,请使用map
:
val str = strOption.map(_.drop(1)).getOrElse("default")
如果要执行一些返回不同类型的处理,请使用fold
:
val strLen = strOption.fold(0)(_.length)
请注意,在这种情况下,默认值位于计算之前。
答案 3 :(得分:-2)
您可以这样做。
val strOption :Option[String] = Some("test")
val str :String = strOption.getOrElse("")
print(str) // test
或者您可以这样做。
// your logic inside the function
def otherOperation(inputStr:String):
println(inputStr)
strOption.map(str :String => otherOpration(str))
这是获得str的方式,您可以在任何需要的地方使用它。其中otherOperation是要使用该str的函数。