Scala中变量和函数:
在Java中定义语法为:
Type varName = value ;//数据类型 变量名 值
在Scala中变量定义必须要有修饰符:var、val
Var代表一个变量,val代表一个常量
def main(args: Array[String]): Unit = {
var n =10
n=11
}
//变量可以再次赋值
那么Val(常量),如下图可见,定义没有问题,但是不能再次赋值,不能再次访问,不可改变的
def main(args: Array[String]): Unit = {
val n =10
n=11 //报错 Reassignment to val
}
由图可见,n的值是10,是一个Int类型,调用的方法没有参数,不用写括号,写了的话也是正确的
打印结果:
如果在Scala中你想明确表现出变量的数据类型可以如下写法;
val n:Int =10
//Scala中没有小写的Int,因为没有基本数据类型
我们也可以对类型的名字进行重命名:Type
def main(args: Array[String]): Unit = {
type myint =Int
var n:myint =19
println(n)
}
这样写的好处是,如果将来一个类型是非常长的,查询的列名比较长,你可以起一个别名,引用别名定义数据类型
定义函数:def
使用def关键词来定义函数
做一个简单的例子,两个数字相加
def myadd(i:Int,n:Int):Int =i+n
}
//这里要强调一下,Scala定义方法的时候最后一行作为函数的返回值,不需要加return,加了也不错
Scala还支持函数范型,在JAVA中只支持类范型,函数泛型:想要任意数据类型相加
如果没有表明A的话是任意数据类型,就是Object,两个Object就不能相加了。返回类型也不能要,因为我们这个没有返回类型
def myadd[A](i:A,n:A) ={println(i),println(n)}
}
那我们调用一下:
def main(args: Array[String]): Unit = {
myadd("ss","mm") //这样就代表myadd的范型为String
}
def myadd[A](i:A,n:A) ={println(i),println(n)}
}
如果定义函数时候,如果函数里面定义了一个”推出“的话,此函数就会延迟执行:
object HelloWord extends App{
def square(x:Int):Int ={
//打印参数并返回平方
println(x)
x*x
}
def printByValue(x:Any):Unit={ //普通的
println(x)
println(x)
}
def printByName(x: => Any):Unit={
//定义函数,但是不会执行的,当x这个函数使用Any才开始执行
println(x)
println(x)
}
printByValue(square(5))
}
结果:
5
25
25
那这第一个就是将参数x(5)打印出来,并将x*x的值传入到 printByName方法的参数中,所以结果是5 25 25
那么如果改为用printByName调用的话如何呢:
printByName(square(5))
结果:
5
25
5
25
看起来和第上一次没什么区别,但是它的运行却是这个值延迟运行的,它先执行square,把整个函数作为参数传递给X,那么就会先打印5再返回25
Scala中循环:打印1-10
for (i <-1 to 10){
println(i)
}
隔两个打印一个数
for (i <-1 to 10 by 2){ //by 自增的意思
println(i)
}
13579
所以说由此可以看见Scala是比Java更高级的语言,他的编写代码和自然语言(自己说话的方式)是一样的
我们还可以使用ForEash的方式,和上面效果一样:
(1 to 10 by 2).foreach(
println(_) _的意思是当前,当前这个数
)
但是你如果不想用下划线的话可以如下:
(1 to 10 by 2).foreach( 推出的方式
x =>println(x)
)
我们可以点开Foreach看一下
这里面就是一个推出的方式,所以说这是一个匿名函数
那如果我们单独把 (1 to 10) 这一句拿出来看的话,是一个序列。
var a = (1 to 10)
println(a)
}
结果:inexact Range 1 to 10 by 2
//由此可见,这是一个Range
那我们可以通过如下方式查看:
var a = (1 to 10)
println(a.getClass)
}
结果:
class scala.collection.immutable.Range$Inclusive
// immutable 这个单词的意思是不可变,就是这个Ranage里面的数据不允许改变
如果我有了这个Range,我们怎么处理Range中的数据,都属于集合:Map
例如:对Range里面的所有的数都加2
var a = (1 to 10 by 2)
a.map(x => x+2).foreach(println(_)) //映射的意思,代表对每一个数据做相同的处理并返回
}
结果:
3
4
5
6
7
8
9
10
11
12
如果说想倒1-10中的偶数:filter(过滤)
filter里面要写一个表达式,只能返回Boolean的值,我们可以点进去看一下
var a = (1 to 10)
//a.map(x => x+2).foreach(println(_)) //映射的意思,代表对每一个数据做相同的处理并返回
a.filter(_%2==0).foreach(
println(_)
)
// 下划线代表当前参数, 然后都除以2,也就是说我只想得到1-10中每一个数处以2等于0的数
所以我们学习Scala中主要学习这些容器里面的,我们逐一来看
如果我想得到1-10中的和怎么做:reduce
var a = (1 to 10)
println( a.reduce(_+_)) //要把每个数累加后作为第一个数,第二个参数是要累加的项
结果:
55
由现在看来,Scala对于运算提供了很多函数,比如说把1-10做成偶数一组,奇数一组:groupBy
var a = (1 to 10)
a.groupBy(_%2==0).foreach(println(_))
//通过groupBy,对里面的每一个数除以2,有等于0的,有不等于0的,得到的是一个Key(true false) 和Value(true的value和false的value)
结果:
(false,Vector(1, 3, 5, 7, 9))
(true,Vector(2, 4, 6, 8, 10))
由此可以看见我们可以用很简短的代码就能完成数据统计这件事
Scala类的数据结构:
Scala所有类型都是Object,顶级的类叫做ScalaObject.我们定义的所有的类都叫做ScalaObject
ScalaObject下面呢就是最根基的类叫做Any,就是任意类型,下面两个体系 值类型(AnyVal)和引用类型(AnyRef)
把数值着一些类型(Int Boolean char..)这一些归为值类型(AnyVal)
把String和数组,列表着一些都归为引用类型(AnyRef)
Null:是一个类,在Java和Scala中小写的Null是一个值,大写的Null是一个类,类型,不允许再被继承,是一个终止的特征,继承了引用类型(AnyRef)
Nothing:没有实例对象的一种数据类型,它的父类是Any(顶级的)
Unit代表的是一个值类型,值类型,没有任何值