scala成长之路(1)基本语法和数据类型
scala作为JVM上的Lisp,是一种geek类型的编程语言,也一直是我等java程序员眼中的梦寐以求的一门技能,遂下定决心花一段时间好好学习scala。第一天学习,主要介绍与java在编程上的主要区别。
首先,scala默认导入了java.lang包下的所有类,因此在scala中可以直接使用所有该包下的所有类,例如System、String
1. scala与java不同的一点是:scala是完全面向对象的,它没有基本数据类型,所有的变量、字面量或常量都是对象,所以你可以看到这种调用方式
scala> 1.toString()
res3: String = 1
因此,scala的数据类型基本都与java的基本数据类型包装类相对应:
数据类型 | 描述 |
---|---|
Byte | 8位有符号补码整数。数值区间为 -128 到 127 |
Short | 16位有符号补码整数。数值区间为 -32768 到 32767 |
Int | 32位有符号补码整数。数值区间为 -2147483648 到 2147483647 |
Long | 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807 |
Float | 32 位, IEEE 754标准的单精度浮点数 |
Double | 32 位 IEEE 754标准的单精度浮点数 |
Char | 16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF |
String | 字符序列 |
Boolean | true或false |
Unit | 表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。 |
Null | null 或空引用 |
Nothing | Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型。 |
Any | Any是所有其他类的超类 |
AnyRef | AnyRef类是Scala里所有引用类(reference class)的基类 |
注意其中的Unit类型,它和null不一样,null只能用于引用类型,不能用于数据类型:
scala> var a : Int = null
<console>:11: error: an expression of type Null is ineligible for implicit conversion
var a : Int = null
而Unit类型更多的是用于返回值表示没有返回值,也即返回值为空。scala中每个表达式都有返回值,但与c语言不同的是,scala中赋值表达式的返回值为空;而且scala中每个代码块都有返回值,即为代码块最后一行的返回值:
scala> var a = {println("hello world");var b = "aaa";b += "ccc"}
hello world
a: Unit = ()
2. 与其他函数式编程语言一样,函数在scala里也被视为“一等公民”,即函数可赋值,可作为参数进行传递,可作为返回值:
3. scala的for循环与java有所不同,它类似于python,只能用于遍历某个集合(但python还是可以通过enumerate来获得当前元素的位置信息,而scala则无此功能):
scala> for(i<-1 to 10)
| print(i + ",")
1,2,3,4,5,6,7,8,9,10,
同时,for循环的嵌套可以写在用一个for中,不同的层次之间用分号;链接:
for(i <- 1 to 9;j <- 1 to 3){
printf("%d,%d\n",i,j)
}
4. Array, List, Set, Map
首先需要明确,scala中的这四种容器类与java都是完全不同的,scala中除Tuple之外,所有容器都有类型指定
(1)Array是定长可变容器,类似于java中的list的定长版本,而且Array还需指定元素类型类似于java的泛型,注意使用的是中括号[]:
scala> var a = new Array[String](3)
a: Array[String] = Array(null, null, null)
如果使用显示初始化,则不需要new,类型自动推断:
scala> var a = Array(1,"12")
a: Array[Any] = Array(1, 12)
需要指出的是,在scala中,直接调用任何类的(),都等价于其apply方法,所以前边的程序也可以写作:var b = Array.apply(1,2,3)。而Array的索引下标则从0开始,可以修改任意元素的值:a(1) = 32,其等价于a.update(1,32)。此外,Array虽然是定长的,但是可以拼接其他可迭代容器,使用++生成一个新的Array:
scala> a ++ b
res10: Array[Int] = Array(1, 2, 3, 4)
(2)List是定长的不可修改容器,因此只能使用显式初始化:var a = List(1,3,4)。同时,List也提供类似的添加和拼接功能,分别利用:::和::进行List间的拼接以及添加元素:
var a = List(1,2,3)
var b = List(4,5,6)
a:::b
7::a
res17: List[Int] = List(7, 1, 2, 3)
需要注意的是,:::以及::都是右结合操作符,即将7添加到a应该是7::a而不是a::7,是右边的元素为操作方,左边为参数,同理,有一种创建List的方法:
scala> 1::2::3::Nil
res22: List[Int] = List(1, 2, 3)
其中Nil为默认导入的单例,其为一个空List
list的元素是不可变的,试图向其中的元素赋值会报错
scala> a(1) = 3
<console>:13: error: value update is not a member of List[Any] (从这里也可以看出等号左边的括号()解释器实际将其解释为update方法)
a(1) = 3
注意,List和Array都有个特点:一旦确定容器的类型,那么从容其中取出的元素也会默认为该类型,例如上边的 a由于在创建时指定了两种类型,则将List定位他们的公共父类:Any
scala> a(1)
res25: Any = aaa
(3)Tuple比较简单,它也许不能称为一种容器,它也是元素不可变的,但是它没有指定类型,即它可以同时容纳多种类型,取出时仍然是自身的类型:
scala> var b = (1,true,"a",2.2)
b: (Int, Boolean, String, Double) = (1,true,a,2.2)
Tuple有长度限制,最长为22,取出时也很特殊:b._1, b._2,下标从1开始
(4)Set和Map
Set和Map都有两种不同的实现:Mutable (可变)和 Immutable (不可变)
需要指出的是,默认直接使用的Set和Map都是不可变的,即默认导入的是scala.collection.immutable.Map和scala.collection.mutable.Set。
Set就是一个集合,主要用于迭代,要求其中的元素不能有重复。
Map 的基本用法如下( Map 类似于其它语言中的关联数组如 PHP )
val romanNumeral = Map ( 1 -> "I" , 2 -> "II",
3 -> "III", 4 -> "IV", 5 -> "V")
println (romanNumeral(4))
scala成长之路(1)基本语法和数据类型的更多相关文章
- scala成长之路(7)函数进阶——可能是史上最浅显易懂的闭包教程
由于scala中函数内部能定义函数,且函数能作为函数的返回值,那么问题来了,当返回的函数使用了外层函数的局部变量时,会发生什么呢?没错,就产生是闭包. 关于闭包的解释网上一大堆,但基本上都是照葫芦画瓢 ...
- scala成长之路(6)函数入门
众所周知,scala作为一门极客型的函数式编程语言,支持的特性包括: 函数拥有“一等公民”身份: 支持匿名函数(函数字面量) 支持高阶函数 支持闭包 部分应用函数 柯里化 首先需要指出,在scala中 ...
- scala成长之路(5)问题记录
还是在看scala sdk源码的时候,有很多问题要考自己慢慢摸索,这里做个记录. 一. 隐式转换的作用域? 隐式转换需要三个因素 1. 己方(当前对象) 2. 转换函数 3. 对方(转换的目标类) 这 ...
- scala成长之路(4)compaion object——伴生对象的使用
虽然java一直声称自己是完全面向对象的语言,但一直以来都被很多人所质疑,其中java的静态成员函数就是主要的“罪魁祸首”.由于java中保留了静态方法的调用,导致其编程模式依然有过程式编程的可能,尤 ...
- scala成长之路(3)隐式转换
不废话,先上例子:定义一个参数类型为String的函数: scala> def sayHello(name:String) = println("hello " + name ...
- scala成长之路(2)对象和类
scala提供了一种特殊的定义单例的方法:object关键字 scala> object Shabi{ | val age = 0 | val name = "shabi" ...
- Scala 学习之路(二)—— 基本数据类型和运算符
一.数据类型 1.1 类型支持 Scala 拥有下表所示的数据类型,其中Byte.Short.Int.Long和Char类型统称为整数类型,整数类型加上Float和Double统称为数值类型.Scal ...
- Scala进阶之路-Scala高级语法之隐式(implicit)详解
Scala进阶之路-Scala高级语法之隐式(implicit)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们调用别人的框架,发现少了一些方法,需要添加,但是让别人为你一 ...
- Scala进阶之路-Scala的基本语法
Scala进阶之路-Scala的基本语法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数式编程初体验Spark-Shell之WordCount var arr=Array( ...
随机推荐
- 使用 profile 进行python代码性能分析
定位程序性能瓶颈 对代码优化的前提是需要了解性能瓶颈在什么地方,程序运行的主要时间是消耗在哪里,对于比较复杂的代码可以借助一些工具来定位,python 内置了丰富的性能分析工具,如 profile,c ...
- SQL Server ->> Move characters in string N position(s) forward/backward based on ASCII table(根据ASCII表的排列顺序将字符串内的数值往前或者后移N个位)
去年无聊的时候想到想玩一下根据ASCII表的排列顺序将字符串内的数值往前或者后移N个位,顺便看一下是T-SQL性能好还是用C#写CLR函数处理得快.结果是在50万行以下其实两者差距很小,当然这是在我的 ...
- ASP.NET中引用dll“找不到指定模块"的完美解决办法 z
DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息.DllImport属性应用于方法,要求最少要 ...
- (四)WebDriver常用方法
点击和输入 前面我们已经学习了定位元素, 定位只是第一步, 定位之后需要对这个元素进行操作, 或单击(按钮) 或输入(输入框) , 下面就来认识 WebDriver 中最常用的几个方法: clear( ...
- 免费的SSL证书,你值得拥有!Let's Encrypt 试用体验记录
早上收到 Let’s Encrypt 的邮件,说偶之前申请的已经通过了,于是马上开始试用.Let’s Encrypt 是一个新的数字证书认证机构,它通过自动化的过程消除创建和安装证书的复杂性,为网站提 ...
- ORACLE不使用工具的情况下获取对象DDL
set line 200set pagesize 0set long 99999set feedback offset echo off获得表.索引.视图.存储过程.函数的DDL:select dbm ...
- 常用的shell语句 【awk】去重,排列
目的:从日志access.log中,筛选出IP来,并统计每个IP出现的次数,然后显示出来. 因为:awk = 扒IP shot = 排序 uniq = 去重 所以:awk '{print $1} ...
- June 05th 2017 Week 23rd Monday
No great discovery was ever made without a bold guess. 没有大胆的猜测就没有伟大的发现. I've read this sentence just ...
- 2019年5月训练记录(更新ing)
前言 \(ZJOI\)正式结束了. 但期中考试只考了年级\(216\),退役既视感... 于是就被抓回去补文化课了. 下半个学期可能要以文化课为主了吧! 但周三.周日应该还是会正常参加训练的,但其他时 ...
- 【洛谷5292】[HNOI2019] 校园旅行(思维DP)
点此看题面 大致题意: 给你一张无向图,每个点权值为\(0\)或\(1\),多组询问两点之间是否存在一条回文路径. 暴力\(DP\) 首先,看到\(n\)如此之小(\(n\le5000\)),便容易想 ...