一门多范式的编程语言Scala学习的第一天-简介

news/2024/11/13 13:57:29/文章来源:https://www.cnblogs.com/shmil/p/18370470

Scala

1、Scala简介

1.1Scala的介绍

  • scala是一门多范式的编程语言
  • Scala是把函数式编程思想和面向对象编程思想结合的一种编程语言
  • 大数据计算引擎spark是由Scala编写的

1.2Scala的特性

1.2.1多范式

1.2.1.1面向对象特性

Scala 是一种高度表达性的编程语言,它结合了面向对象编程和函数式编程的最佳特性

  • 类和对象:Scala支持类和对象,可以定义属性和方法。
  • 继承和多态:支持类的继承和多态,可以创建层次结构和重用代码。
  • 抽象类:可以定义抽象类,用于定义接口和实现部分行为
  • 封装:支持访问控制修饰符(public,protected,private),实现数据的封装
1.2.1.2函数式编程
  • 高阶函数:函数可以作为参数传递给另一个函数,或者从另一个函数返回。
  • 不可变性:默认使用不可变数据结构,提高代码的并发安全性。
  • 模式匹配:提供强大的模式匹配功能,可以解构复杂数据结构,进行条件判断。

1.2.2兼容JAVA

  • 类库调用
  • 互操作

1.2.3语法简洁

  • 代码行短
  • 类型推断
  • 抽象控制

1.2.4静态类型化

  • 可检验、安全重构

1.2.5支持并发控制

  • 强计算能力、自定义其他控制结构

1.3面向函数式编程和面向对象编程的区别

  • 在面向对象编程中,我们把对象传来传去,那在函数式编程中,我们要做的是把函数传来传去,而这个,说成术语,我们把他叫做高阶函数。
  • 在函数式编程中,函数是基本单位,,他几乎被用作一切,包括最简单的计算,甚至连变量都被计算所取代。在函数式编程中,变量只是一个名称,而不是一个存储单元,这是函数式编程与传统的命令式编程最典型的不同之处。

1.4Scala和Java的编译过程

  • 以Scala结尾的文件和以Java结尾的文件都会通过编译之后生成 .class文件,
  • 并且由于Scala是基于Java的,因此两者编译之后产生的 .class文件是一样的
  • 然后相应的 .class文件会在JVM上运行,产生最终的结果

image-20240710191704602

2、Scala的相关基础用法

注意事项

  • 1、如果需要是可运行文件就必须将class改成object
    
  • 2、如果是class仅仅代表的是一个类,如果是object就代表的是一个单例对象
    
  • 3、在Scala中,编写完一句代码结尾不需要加上";"
    
  • 4、Scala文件中可以任意的使用Java的类和方法
    

Scala的第一个代码,hello world

object demo01HelloWord {def main(args: Array[String]): Unit = {println("hello world")}
}

2.1变量与常量

2.1.1变量

变量: 在程序运行过程中其值可能发生改变的量叫做变量。

object Demo02base {def main(args: Array[String]): Unit = {/*** 定义变量* 注意:*  1、变量一旦定义类型就确定了,可以不用手动指定变量的类型,Scala会根据赋予的值自动推断出其类型*  2、也可以手动的指定变量的数据类型,如:var 变量名:数据类型=值**  Scala中的数据类型和Java数据类型的对应关系*  Java:               scala:* byte                Byte* short               Short* int                 Int* long                Long* float               Float* double              Double* boolean             Boolean* char                Char*/var a1=100println(a1)//获取a1的数据类型println(a1.getClass)//类型不一致无法直接转换a1的值
//    a1="hello"
//    println(a1)//类型一致可以直接改变变量的值a1=200println(a1)//定义一个整数类型的完整写法var a2:Int=100println(a2)println(a2.getClass)// * 其实是一个函数,底层是通过StringBuilder链接字符的//简化写法将.和()省略println("="*50)println("=".*(50))}
}

2.1.2常量

在程序运行过程中其值不会发生变化的量叫做常量

object Demo03base {def main(args: Array[String]): Unit = {   /*** 定义常量:在Scala中定义一个常量,需要使用关键字:val*/val a3:Int=50println(a3)//常量的值一旦定义就无法改变
//    a3=20}
}

2.2字符串

scala中的字符串String类和Java中的String类是共同的一个字符串类

Java中字符串的功能在Scala中正常使用

object Demo04base {def main(args: Array[String]): Unit = {var s3:String="hello,world,java,shujia,scala"val arr1: Array[String] = s3.split(",")//直接打印使用逗号切分的数组,打印的是该数组的地址值println(arr1)//Scala中的数组和Java的数组一致,具有索引且从0开始println(arr1(0))println(arr1(1))println(arr1(2))println(arr1(3))println(arr1(4))/*** scala中的字符串拼接方式:* 1、直接使用+号,这种拼接方式比较消耗性能* 2、使用String Builder的append方法* 3、使用Scala特有的函数mkString,该方法的前提是有一组序列* 4、使用Scala特有的字符串传递方法 s"${变量}" 该方法的底层是使用String Builder方式拼接的*/var q1:String="hello"var q2:String="world"var q3:String="java"//方式1val res1: String = q1 + "|" + q2 + "|" + q3print(res1)//方式2val sb: StringBuilder = new StringBuilder()sb.append(q1).append("-").append(q2).append("-").append(q3)println(sb)//方法3:指定字符串的分隔符val res2: String = arr1.mkString("|")println(res2)//方法4val res3: String = s"${q1.toUpperCase()}#${q2}#${q3}"println(res3)}}

2.3scala的运算符

import java.util.Scanner
import scala.util.control.Breaks._object Demo03 {def main(args: Array[String]): Unit = {/*** scala中的运算符*/var x:Int=3var y:Int=4//这些运算符在Scala中其实都是函数println(x+y)println(x-y)println(x*y)println(x/y)println(x%y)//x乘以1.0之后其数据类型就上升为了double,故结果就会是double类型println(x*1.0/y)println("hello"+4)}
}

2.4条件语句

条件语句分为:

​ 1、选择语句:if

​ 2、循环语句:while,break

  • if语句
//条件语句if
val sc: Scanner = new Scanner(System.in)
println("请输入年龄:")
val age: Int = sc.nextInt()
if(age>18){println("old")
}else{println("young")
}
  • while循环

注意:

​ 1、在Scala语言中,没有++或者--的语法,只有i+=1 或者i-=1

​ 2、在Scala语言中,不存在和Java一样的普通for循环

​ 3、Scala中的for循环写法不一样

//Scala中值存在下面的for循环写法
for(e<-arr1){println(e)
}/*** while循环*/
var i:Int=0
while (i<arr1.length){println(arr1(i))i+=1
}/*** 需求:在控制台中输出10行hello world*/
var j:Int=1
while(j<=10){println("hello world")j+=1
}//使用for循环
for(e<-1 to 10){println(e)
}for(e<-1 until 10){println(e)
}
  • 流程控制语句

注意:在scala中没有break或者continue关键字,但是存在breakable

breakable{for(e<-1 to 10){if(e==5){// 底层实现是一个函数,抛出一个异常,终止程序运行break}println(e)}
}
println("hello")

2.5 Scala中的IO流

注意:对于Scala来说,不存在写文件的方式,有读取文件的方式

  • 采用Java中写文件的方式写入,如果文件不存在,则会自动进行创建

  • 但是对于读文件,如果文件不存在时会报错

package com.shujia.jichuimport java.io.{BufferedReader, BufferedWriter, FileReader, FileWriter}
import scala.io.{BufferedSource, Source}
object Demo03base3 {def main(args: Array[String]): Unit = {/*** scala中的读取文件的方式* Source.fromFil 底层是使用了字节输入流读取数据FileInputStream*/val bs: BufferedSource = Source.fromFile("scala/data/words.txt")val iterator: Iterator[String] = bs.getLines()while (iterator.hasNext){val str: String = iterator.next()println(str)}//使用for循环的方法for(e<-bs.getLines()){println(e)}val bw: BufferedWriter = new BufferedWriter(new FileWriter("scala/data/words3.txt"))bw.write("hello shujia")bw.newLine()bw.write("java")//刷写进入文件bw.flush()}
}

2.6异常处理

  • Scala中的异常处理和Java中的类似
object Demo04Exception {def main(args: Array[String]): Unit = {try{println(0/0)//如果上面的错误没有被抛出,使用catch的方式处理,那么下面的语句不会执行val arr1: Array[Int] = Array(1, 2, 3, 4)println(arr1(4))}catch{//相当于sql语句中的case whencase e:ArithmeticException=>println("除0异常")e.printStackTrace()case e:ArrayIndexOutOfBoundsException=>println("数组越界")e.printStackTrace()case _ =>println("出现异常")}finally {//今后finally中的处理大部分情况下都与释放资源有关println("finally")}}
}//上面是对异常进行捕获的方式,也可以对异常进行抛出
val sc: Scanner = new Scanner(System.in)
println("输入除数:")
val css: Int = sc.nextInt()
if (css != 0) {println(10 / css)
} else {throw new ArithmeticException("除数为0")
}

2.7函数

/*** def: 定义函数或者方法的关键字* main: 是函数或者方法的名字,符合标识符的命名规则* args: 函数形参的名字* Array[String]: 参数的数据类型是一个元素为字符串的数组* =: 后面跟着函数体* Unit: 等同于java中的void 表示无返回值的意思*** def main(args: Array[String]): Unit = {** }** 在不同的地方定义,称呼不一样* 函数:在object中定义的叫做函数* 方法:在class中定义的叫做方法*/
object Demo05Function {def main(args: Array[String]): Unit = {//函数def add(a1:Int,b1:Int):Int={return a1+b1}val res3: Int = Demo05Function.add1(100, 200)def fun1(s1:String):Int={return s1.toInt}val res1: Int = add(3, 4)println(res1)def add2(a1:Int,b1:Int):Int={return a1+b1}val d1: Demo01 = new Demo01()val res2: Int = d1.add2(11, 22)println(res2)//object中的函数调用方式一:可以直接通过类名进行调用,类似于静态方法一样val result1: Int = Demo05Function.add1(3, 4)println(result1)//调用方法二:可以省略类名,直接调用val result2: Int = add1(100, 200)println(result2)//方法三:如果方法调用的函数只有一个参数的时候,可以将.和小括号用空格代替调用val result3: Int = Demo05Function fun2 "1000"println(result3)add5}def add1(a1: Int, b1: Int): Int = {return a1 + b1}def fun2(s1: String): Int = {return s1.toInt}/*** 函数的定义格式* 1、函数有返回值,并且最后一句话作为函数的返回值的时候,return关键字可以不写* 2、函数体只有一句话实现时,大括号可以不写* 3、如果函数没有参数时,小括号可以省略不写*///方法一def add3(a1:Int,b1:Int):Int={a1+b1}//方法二def add4(a1:Int,b1:Int):Int=a1+b1//方法三def add5=println("hello")}
class Demo01{def add2(a1: Int, b1: Int): Int = {return a1 + b1}
}

2.8Scala中的函数递归

递归:方法定义时,调用自身的现象

条件:必须存在函数出口

def main(args: Array[String]): Unit = {val res1: Int = jiecheng(5)println(res1)println(s"5的阶乘是${Demo06Function jiecheng (5)}")
}//求数的阶乘
def jiecheng(num:Int):Int={if(num==1){1}else{num*jiecheng(num-1)}
}

2.9Scala中定义类

定义类的三大要素:构造方法,成员方法,成员变量

构造方法:

  • 1、在scala中构造方法的编写和在java中不太一样,类所拥有的大括号中都是构造代码块的内容
    2、默认情况下,每一个类都应该提供一个无参的构造方法
    3、构造方法可以有许多
    
object Demo07class {def main(args: Array[String]): Unit = {val stu1: student = new student("zhangsan",19)println(stu1)val stu2: student = new student("zhangsan", 18, "nv")println(stu2)//如果调用的是一个函数的无参构造方法,那么小括号可以不用写val stu3: Student2 = new Student2stu3.fun1()//也可以使用多态的方式创建对象//多态:父类引用,指向子类对象val stu4: Object = new student("lisi", 19, "nan")println(stu4.toString)}
}class student(name:String,age:Int){//相当于构造代码块中的内容
//  println("hello world")/*** 定义成员变量*/val _name:String=nameval _age:Int=age//下划线表示将来会给其赋予默认值var _gender:String= _/*** 构造方法可以写多个*/def this(name:String,age:Int,gender:String){this(name:String,age:Int)_gender=gender}/*** 也可以重写其方法*///  override def toString:String=super.toStringoverride def toString: String = {"姓名:" + _name + ", 年龄:" + _age + ", 性别:" + _gender}
}class Student2{def fun1()=println("shujia666")
}

2.10样例类

  • Scala中非常重要的功能:样例类
  • 其最重要的特性是:
    • 减少创建类时编写的代码两,只需要定义成员变量即可,
    • 样例类会自动扩充成员变量,构造方法,并且自动重写了toString等方法
object Demo08caseClass {def main(args: Array[String]): Unit = {val t1: Teacher = new Teacher("zhangsan", 20, "shuijiao")println(t1.toString)println(t1.name)println(t1.age)println(t1.like)//    t1.name="lisi"t1.like="eat"println(t1.like)}}
/*** 样例类中的成员变量,编译后默认是被jvm添加了final关键字,用户是改变不了的* 对于scala来说,默认是被val修饰的* 如果将来想要被改变,定义的时候需要使用var进行修饰*/
case class Teacher(name:String,age:Int,var like:String)

2.11 伴生对象

  • 在一个Scala文件中

    • 如果一个object对象的名字和定义的class类名一样的话,那么称这个object是该class类的伴生对象
      直接在main函数中调用object的名字就相当于调用该object中的apply方法
      而一般在这个apply方法中会new创建一个上述的类的对象,便于直接调用
      
object Demo09apply {def main(args: Array[String]): Unit = {//普通使用的方法val book: Book = Book.apply("shujia", 666)println(book)//使用伴生对象的方式,调用object的名字就相当于调用该object中的apply方法val book1: Book = Book("shujia", 666)println(book1)}}object Book{def apply(name:String,price:Int): Book = {new Book(name,price)}
}class Book(name:String,price:Int){val _name:String=nameval _price:Int=priceoverride def toString: String = "书名:" + _name + ", 价格:" + _price
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/784540.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VSCode系列 - 如何用VSCode搭建C++高效开发环境(1)

VSCode是笔者用过的最好用的开发工具,没有之一。笔者14年的码龄生涯中,先后用过Eclipse、 IntelliJ IDEA、 WebStorm、 PyCharm、 Visual Studio(2010/2013/2015)、 NetBeans、 Sublime Text等,但自从用VSCode之后,就再没换过其他工具,一直用到现在有5年多的时间。 1. 本文…

[PHP GD Study]我的世界皮肤转迷你世界

涉及图片旋转、放大、复制 目前仅实现了头部的复制 准备工作:迷你世界皮肤底图(命名为miniw.png):我的世界皮肤:源代码: ⚠AI生成 <?php // 设置上传文件的目标目录 $target_dir = "uploads/"; // 创建目标目录如果不存在 if (!file_exists($target_dir)) …

合同等文档的比对实现测试

记录一下合同等文档的比对测试,以下是实现docx格式与txt格式的内容对比结果图,其中图1为docx格式,是房屋租赁合同的内容对比结果;图2是纯文本txt格式的内容对比结果。图1图2

SourceTree离线安装

需求:要求在内网环境开发,连不上外网,安装sourceTree又是需要联网的,这就是尴尬了又不想用命令,已经习惯了sourceTree. 不说废话,上干货: 注意!!!一定按照步骤来,否则不会生效的。 注意!!!一定按照步骤来,否则不会生效的。 注意!!!一定按照步骤来,否则不会生…

037、Vue3+TypeScript基础,使用router.push进行导航式路由跳转

01、main.js代码如下:// 引入createApp用于创建Vue实例 import {createApp} from vue // 引入App.vue根组件 import App from ./App.vue//引入路由 import router from ./routerconst app = createApp(App); //使用路由 app.use(router); // App.vue的根元素id为app app.mount…

WPF:静态、动态资源以及资源词典

WPF:静态、动态资源以及资源词典 静态资源与动态资源 我们常常会使用样式或者控件模板放在Window.Resources中,比如这样:静态资源与动态资源使用如下: <Window.Resources><SolidColorBrush x:Key="SolidColor" Color="#FF0000" /> </Win…

Hat靶场

Hat靶机的ip是192.168.200.8先用nmap扫描一下靶机所有的端口 nmap -p- 192.168.200.8 发现22端口不知道是否开放 还有一个65535 的unkown端口详细查看一下65535端口的信息 nmap -p 65535 -sV 192.168.200.8 貌似是个ftp 但是尝试匿名连接是连接不上去的dirsearch扫描了一下80端…

.NET 智能组件完全开源

Daniel Roth在2024年3月20日发布了一篇文章: .NET 智能组件简介 – AI 驱动的 UI 控件。文章主要介绍了.NET Smart Components,这是一系列可以快速轻松地添加到.NET应用程序中的AI驱动的UI组件。这些组件旨在简化在现有软件中添加AI功能的过程,无需花费大量时间重新设计用户体…

Ros2 Moveit2 - Robot Model and Robot State

Robot Model and Robot State 在本节中,我们将向您介绍用于在 MoveIt 中使用运动学的 C++ API。 RobotModel 和 RobotState 类 RobotModel 和 RobotState 类是提供对机器人运动学访问权限的核心类。 RobotModel 类包含所有链接和关节之间的关系,包括从 URDF 加载的关节限制属…

用友crm客户关系管理help.php存在任意文件读取漏洞

产品介绍: 用友U8CRM模块是一个综合性的客户关系管理系统,旨在帮助企业从客户出发,以客户关系为管理对象,通过动态管理客户信息、获得 客户知识和评判客户价值状况,来全面提升并保持企业的竞争优势及盈利能力。Fofa语句:body="用友 U8CRM"pocGET /pub/help.php…

史上最全:大厂P6/P7/P8 的职业技能,薪资水平,成长路线 ,最全的对照表。 (建议 收藏,慢慢查)

文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,…

『模拟赛』暑假集训CSP提高模拟25

『模拟赛记录』暑假集训CSP提高模拟25Rank 学新东西,不算挂分(确信。A. 可持久化线段树 原板子[SP11470] TTM - To the moon 主席树,不过区间修改。 赛时想到标记永久化了,不过打 pushdown 的时候没新开点,于是 -100pts。 还挺简单的,建树和更改动态开点,按线段树来,加…