scala的Option中的Some和None_scala some-程序员宅基地

大多数语言都有一个特殊的关键字或者对象来表示一个对象引用的是“无”,在Java,它是null。在java中,null是一个关键字,不是一个对象,所以对它调用任何方法都是非法的。但是这对语言设计者来说是一件令人疑惑的选择。为什么要在程序员希望返回一个对象的时候返回一个关键字呢?

为了让所有东西都是对象的目标更加一致,也为了遵循函数式编程的习惯,Scala鼓励你在变量和函数返回值可能不会引用任何值的时候使用Option类型。在没有值的时候,使用None,这是Option的一个子类。如果有值可以引用,就会使用Some来包含这个值。Some也是Option的一个子类。

None被声明为一个对象,而不是一个类。因为我们只需要他的一个实例。这样,它多少有点像null关键字,但它却是一个实实在在的,有方法的对象。

1.Option类型的值通常作为Scala集合类型(List、Map等)操作的返回类型。比如Map的get方法;

object Test {
  def main(args: Array[String]): Unit = {
   //Option类型的值通常作为Scala集合类型(List,Map等)操作的返回类型。比如Map的get方法:
    val test: Map[String, String] = Map("France" -> "Paris", "Japan" -> "Tokyo", "China" -> "Beijing")
    val maybeString: Option[String] = test.get("France")
    println(maybeString)
    val maybeString1 = test.get("hanguo")
    println(maybeString1)
  }
  
}

结果:  

2. Option有两个子类别,Some和None。当程序回传Some的时候,代表这个函式成功地给了你一个String,而你可以透过get()函数拿到那个String,如果程序返回的是None,则代表没有字符串可以给你。

在返回None,也就是没有String给你的时候,如果你还硬要调用get()来取得 String 的话,Scala一样是会抛出一个NoSuchElementException异常给你的

object Test {
  def main(args: Array[String]): Unit = {
    //    //Option类型的值通常作为Scala集合类型(List,Map等)操作的返回类型。比如Map的get方法:
    val test: Map[String, String] = Map("France" -> "Paris", "Japan" -> "Tokyo", "China" -> "Beijing")
    val maybeString: Option[String] = test.get("France")
    println(maybeString)
    val maybeString1: Option[String] = test.get("hanguo")
    println(maybeString1)

    val value: String = maybeString.get
    println(value)
    val value1 = maybeString1.get
    println(value1)

  }

}

运行结果:

3.我们也可以选用另一个方法,getOrElse。这个方法在这个Option是Some的实例时返回对应的值,而在是None的实例时返回传入的参数。换句话说,传入getOrElse的参数实际上是默认返回值。

object Test {
  def main(args: Array[String]): Unit = {
    val test: Map[String, String] = Map("France" -> "Paris", "Japan" -> "Tokyo", "China" -> "Beijing")
    val maybeString: Option[String] = test.get("France")
    val str: String = maybeString.getOrElse("空值")
    println(str)
    val maybeString1: Option[String] = test.get("hanguo")
    val str1: String = maybeString1.getOrElse("空值")
    println(str1)
  }

}

运行结果:

4.通过模式匹配分离可选值,如果匹配的值是Some的话,将Some里的值抽出赋给x变量:

object Test {
  def main(args: Array[String]): Unit = {
    val test: Map[String, String] = Map("France" -> "Paris", "Japan" -> "Tokyo", "China" -> "Beijing")
    val maybeString: Option[String] = test.get("France")
    val unit: Any = showCapital(maybeString)
    println(unit)
    val maybeString1: Option[String] = test.get("hanguo")
    val unit1: Any = showCapital(maybeString1)
    println(unit1)

  }
  def showCapital(x:Option[String])=x match {
    case Some(s)=>s
    case None=>"?"
  }

}

运行结果:

在Scala里Option[T]实际上是一个容器,就像数组或是List一样,你可以把他看成是一个可能有零到一个元素的List。
当你的Option里面有东西的时候,这个List的长度是1(也就是 Some),而当你的Option里没有东西的时候,它的长度是0(也就是 None)。
for循环
如果我们把Option当成一般的List来用,并且用一个for循环来走访这个Option的时候,如果Option是None,那这个for循环里的程序代码自然不会执行,于是我们就达到了不用检查Option是否为None这件事。

代码里我们用 showContentLen 方法测试:

object Test {
  def main(args: Array[String]): Unit = {
    val test: Map[String, String] = Map("France" -> "Paris", "Japan" -> "Tokyo", "China" -> "Beijing")
    val maybeString: Option[String] = test.get("Fance")
    val unit: Any = showCapital(maybeString)
    showContentLen(maybeString)
    println(unit)
    val maybeString1: Option[String] = test.get("hanguo")
    val unit1: Any = showCapital(maybeString1)
    showContentLen(maybeString1)
    println(unit1)

  }
  def showCapital(x:Option[String])=x match {
    case Some(s)=>s
    case None=>"?"
  }
  def showContentLen(x:Option[String])={
    for (c<-x){
      println("长度为:"+c.length)
    }
  }

}

运行结果:

5.map操作
在函数式编程中有一个核心的概念之一是转换,所以大部份支持函数式编程语言,都支持一种叫map()的动作,这个动作是可以帮你把某个容器的内容,套上一些动作之后,变成另一个新的容器。
现在我们考虑如何用Option的map方法实现length: xxx的输出形式:

object Test {
  def main(args: Array[String]): Unit = {
    val test: Map[String, String] = Map("France" -> "Paris", "Japan" -> "Tokyo", "China" -> "Beijing")
    val maybeString: Option[String] = test.get("France")
    val maybeString2: Option[String] = maybeString.map(_.length).map("length:"+_)
    println(maybeString2)
    maybeString2.foreach(print)

  }
}

运行结果:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45034355/article/details/103265988

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法