当前位置: 首页 > article >正文

Scala 的那些奇怪的符号 (一)

    Scala的语法很多,有些人认为过于繁琐,有些人却认为正是因为繁琐,所以才让这门语言严谨和强大。

   例如在翻阅Scala资料或者查看Scala源码的时候,经常会看到“<:”和“>:”,这是什么鬼?下面我就来探讨一下这两个符号的用法:

 

“<:”符号

 

我们定义一个类:“Earth”

 

class Earth {def sound(){println("hello !")}
}

 

 

 

我们定义了一个子类:“Animal”

 

 
 
class Animal extends Earth{ override def sound() ={ println("animal sound") } }

然后 ,还有Animal 的一个子类 “Bird”

 

 

 
class Bird extends Animal{ override def sound()={ print("bird sounds") } }

最后,又定义了一个函数:

 

 

 
def biophony[T <: Animal](things: Seq[T]) = things map (_.sound)

 

 

 

乍一看:这tm是什么鬼?“<:”是什么意思?

其实, 这属于Scala泛型中的知识:上边界和下边界。上边界是“<:”,下边界是“>:”;T <: Animal的意思是:T必须是Animal的子类。这样一来,我们再看看这个函数的意思:定义了一个叫“biophony”的函数,这个函数的参数必须传一个集合,一个什么样的集合呢?Animal 子类或者是Animal的集合(包含Animal)。函数右边就很好理解了,map中每个元素调用了sound方法。

知道了是什么之后,接着调用就很简单了:

 

  biophony(Seq(new Bird, new Bird))

 

 

 

这样一来就输出:

bird sounds
bird sounds

完美!

假如因为可以包含Animal所以,这么调用也可以:

 

   biophony(Seq(new Animal, new Animal))

输出:

 

animal sound
animal sound

甚至可以一个Animal,一个Bird,多态嘛!

 

  biophony(Seq(new Animal, new Bird))

 

 

 

输出:

animal sound
bird sounds

但是,这样就不可以了:

 

  biophony(Seq(new Earth, new Earth))

输出:

 

报错!

Scala的定义了一个“界限”来规定泛型可以适用的在继承关系中的范围,“<:”是上限,表示不超过XXX

 

“>:”符号

 

 

我们把“<:”换成了“>:”

 

 
def biophony[T >: Animal](things: Seq[T]) = things map (_.sound())

不对这怎么还报红了呢?细细想来,Animal的父类的话,不能确定能不能有sound()方法呀,因为父类太多了,Object还是呢。报错也正常,我们就直接返回 things吧

 

 

  def biophony[T >: Animal](things: Seq[T]) = things 

好了,这下好了,不报红了,我们传一个Animal的父类“Earth”的队列,然后没个元素调用“sound()”方法

 

 

  biophony(Seq(new Earth, new Earth)).map(_.sound())

输出:

 

hello !
hello !

之前的结论,调用Animal也应该是可以的:

 

  biophony(Seq(new Animal, new Animal)).map(_.sound())

 

输出:

animal sound
animal sound

好的,也是正确的。假如我们传Animal子类Bird看看会不会报错

 

  biophony(Seq(new Bird, new Bird)).map(_.sound())

输出:

 

bird sounds
bird sounds

居然不报错!还运行了!这是怎么回事??

我们看一下传Bird后的返回值是什么:

是Animal !真相大白了,由于Bird是子类,Scala把Bird当做Animal来处理了。也就是说,“>:”的时候,传任何参数都可以,但是返回值回有所不同,Animal的子类都会统一按照Animal来处理!

那我们传一个和Animal毫不相关的类,会出现什么情况呢?

 

class Moon {}

 

 

 

写了一个Moon,然后按照如下文传参调用

 

  biophony(Seq(new Moon, new Moon))

不报错!

 

我们看一下返回值:

Object!Scala把它看做了Object。也就是说,可以随便传!只不过和Animal直系的,是Animal父类的还是父类处理,是Animal子类的按照Animal处理,和Animal无关的,一律按照Object处理!

更多精彩内容,请关注我的微信公众账号 互联网技术窝

 

http://www.lryc.cn/news/2413666.html

相关文章:

  • 用户行为分析的背景以及几种模型分析、实例分析——淘宝用户行为分析
  • ASP进行数据库查询时SQL语句的几种特殊用法
  • 在线网址URL生成二维码的API接口
  • 一个Springboot项目页面中CSS,JS文件加载失败的问题
  • 包括遗传算法在内的现代优化算法简介
  • 从零开始的Android学习之路:一、AndroidStudio的安装以及安卓开发环境的配置
  • 开源项目 `blog` 使用教程
  • datagridview设置选中行_pycharm常用快捷键和设置
  • 智能ABC输入法使用技巧
  • 网络安全入门教程(非常详细)从零基础入门到精通,看完这一篇就够了。_网络安全教程
  • KVM 介绍
  • python编程有什么用处,python编程主要学什么
  • 风云决动画好看吗??
  • FreeTextBox使用详解(FTBv3-1-6)
  • 【无线安全实践入门】破解WiFi密码的多个方法
  • 开根号计算机在线应用,根号计算器(万能计算器在线计算)
  • debugbar php漏洞,Laravel-debugbar 开发调试利器
  • Nodejs基础
  • CVE-2015-0235
  • python心理学实验平台,python心理学实验程序(psychopy)
  • 一个不错的网站,颜色推荐 http://www.colorhexa.com/
  • [ Python 库调用和管理 ] __init__.py 的基本使用和运作机制
  • js常见特效
  • 了解遗传算法
  • Web.xml配置之context-param
  • 密码学 / PKI 体系概述
  • C++ 算法篇 深度优先搜索(DFS)
  • 《帝国时代3:决定版》dll丢失?修复x3daudio1_7.dll文件指南
  • Ubuntu 中 安装ulipad 发现无法更新软件库,无法安装python-wxgtk2.8
  • APIHOOK实例剖析