第一个 Scala 程序

shell里面输入

$ scala
scala> 1 + 1
res0: Int = 2 scala> println("Hello World!")
Hello World!

文件形式

object HelloWorld {
/* 这是我的第一个 Scala 程序
* 以下程序将输出'Hello World!'
*/
def main(args: Array[String]) = {
println("Hello, world!") // 输出 Hello World
}
}

接下来我们使用 scalac 命令编译它:

$ scalac HelloWorld.scala
$ ls
HelloWorld$.class HelloWorld.scala
HelloWorld.class

编译后我们可以看到目录下生成了 HelloWorld.class 文件,该文件可以在Java Virtual Machine (JVM)上运行。

编译后,我们可以使用以下命令来执行程序:

$ scala HelloWorld
Hello, world!

基本语法

Scala是运行在jvm上面的一款语言,在语法和概念上难免和java会有相似之处,而java的语法和C语法一脉相承,所以有C基础的话基本语法还是比较好上手的。

Scala有两个设计理念:面向对象(OOP)和函数式编程(FP)

面向对象就导致Scala中万物皆对象;函数式这个概念比较陌生,后续会单独介绍。

1.变量

使用关键词 "var" 声明变量,使用关键词 "val" 声明常量。

声明变量实例如下:

var myVar : String = "Foo"
var myVar : String = "Too"

Scala是一个静态类型语言,但编译器能自动推断类型

所以上面能这么写,效果一样:

var myVar = "Foo"
var myVar = "Too"

2.数据类型

然而,我们说scala是一款万物皆对象的语言,这些变量都是对象

这就类似于java中的封装类(Scala的底层实现确实也是用的java的封装类)

Scala 与 Java有着相同的数据类型,下表列出了 Scala 支持的数据类型:

数据类型 描述
Byte 8位有符号补码整数。数值区间为 -128 到 127
Short 16位有符号补码整数。数值区间为 -32768 到 32767
Int 32位有符号补码整数。数值区间为 -2147483648 到 2147483647
Long 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807
Float 32 位, IEEE 754 标准的单精度浮点数
Double 64 位 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)的基类

上表中列出的数据类型都是对象,也就是说scala没有java中的原生类型。在scala是可以对数字等基础类型调用方法的。

(1)整数字面量、浮点字面量

(2)字符串字面量

scala> '1'
res0: Char = 1 scala> "1"
res1: String = 1 scala> "\t"
res2: String = " " scala> """\t"""
res3: String = \t

字符串插值,会对每个表达式求值,并且调用toString方法

scala> val a=2.1
a: Double = 2.1 scala> val s=s"Hi,${a+9}!"
s: String = Hi,11.1!

函数

方法定义

方法定义由一个 def 关键字开始,紧接着是可选的参数列表,一个冒号 : 和方法的返回类型,一个等于号 = ,最后是方法的主体。

Scala 方法定义格式如下:

def functionName ([参数列表]) : [return type] = {
function body
return [expr]
}
  • 以上代码中 return type 可以是任意合法的 Scala 数据类型。参数列表中的参数可以使用逗号分隔。

题外话:scala能使用元组进行打包,返回多个变量,在调用时解构赋值

scala> def useScala() = (1,2,3)

useScala: ()(Int, Int, Int)

scala> val a,b,c = useScala()

a: (Int, Int, Int) = (1,2,3)

b: (Int, Int, Int) = (1,2,3)

c: (Int, Int, Int) = (1,2,3)

  • 函数体最后一行的return推荐省略
  • 等号”=“省略条件:返回类型未显式声明,并且返回类型为Unit,这个类似于 Java 的 void, 实例如下:
object Hello{
def printMe( ){
println("Hello, Scala!")
}
}

方法调用

以下是调用方法的标准格式:

functionName( 参数列表 )

如果方法使用了实例的对象来调用,我们可以使用类似java的格式 (使用 . 号):

[instance.]functionName( 参数列表 )

类和对象

类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是用于创建对象的蓝图,它是一个定义包括在特定类型的对象中的方法和变量的软件模板。

class Point(xc: Int, yc: Int) {
var x: Int = xc
var y: Int = yc def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("x 的坐标点: " + x);
println ("y 的坐标点: " + y);
}
}

构造方法

  1. 主构造方法

    在类内部非字段、非方法的部分全部当作构造函数,在类名后参数列表用于接收。

    可以看一个SpinalHDL生成verilog的写法:

    object MyTopLevelVerilog extends App {
    Config.spinal.generateVerilog(MyTopLevel(4))
    }

    看到App定义:

    trait App extends DelayedInit {
    
      // ...
    
      @deprecatedOverriding("main should not be overridden", "2.11.0")
    def main(args: Array[String]) = {
    this._args = args
    for (proc <- initCode) proc()
    if (util.Properties.propIsSet("scala.time")) {
    val total = currentTime - executionStart
    Console.println("[total " + total + "ms]")
    }
    }
    }
  2. 辅助构造函数

    def this( ... )

    函数内第一句必须调用其他的构造方法this()

  3. 私有主构造方法

    如例所示加上private,构造对象时就不能通过主构造方法创建对象,得用辅助构造方法或工厂方法(用于构造对象的方法)

    class Student private (name: String,n: Int)

类继承

extends关键词

class Child extends Parent{
//...
}

工厂对象和工厂方法

如果定义一个专门用来构造某一个类的对象的方法,那么这种方法就被称为“工厂方法”。包含这些工厂方法集合的单例对象,称为“工厂对象”。通常,工厂方法会定义在伴生对象中。尤其是当一系列类存在继承关系时,可以在基类的伴生对象中定义一系列对应的工厂方法。使用工厂方法的好处是可以不用直接使用new来实例化对象,改用方法调用,而且方法名可以是任意的,这样对外隐藏了类的实现细节。

//students. scala
class Students(val name:String,var score:Int){
def exam(s:Int)=score =s
override def toString =name +"'s score is "+score +"."
} object Students {
def registerStu(name:String,score:Int)=new Students(name,score)
} //registerStu为工厂方法

用“ import Students._ ”导入单例对象后,就能这样使用:

scala>import Students._
scala>val stu =registerStu("Tim",100)
stu:Students =Tim's score is 100.

重写方法

在函数前面加上关键词override

重写toString方法

class A {
override def toString = "123456A"
}
val a = new A()
println(a)
scala> class A {
| override def toString = "123456A"
| }
// defined class A scala> val a = new A()
val a: A = 123456A scala> println(a)
123456A

Scala 单例对象

在 Scala 中,是没有 static 这个东西的,但是它也为我们提供了单例模式的实现方法,那就是使用关键字 object。

Scala 中使用单例模式时,除了定义的类之外,还要定义一个同名的 object 对象,它和类的区别是,object对象不能带参数。

当单例对象与某个类共享同一个名称时,他被称作是这个类的伴生对象:companion object。你必须在同一个源文件里定义类和它的伴生对象。类被称为是这个单例对象的伴生类:companion class。类和它的伴生对象可以互相访问其私有成员。

class Point(val xc: Int, val yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
}
} object Test {
def main(args: Array[String]) {
val point = new Point(10, 20)
printPoint def printPoint{
println ("x 的坐标点 : " + point.x);
println ("y 的坐标点 : " + point.y);
}
}
}

执行以上代码,输出结果为:

$ scalac Test.scala
$ scala Test
x 的坐标点 : 10
y 的坐标点 : 20

伴生对象

// 私有构造方法
class Marker private(val color:String) { println("创建" + this) override def toString(): String = "颜色标记:"+ color } // 伴生对象,与类名字相同,可以访问类的私有属性和方法
object Marker{ private val markers: Map[String, Marker] = Map(
"red" -> new Marker("red"),
"blue" -> new Marker("blue"),
"green" -> new Marker("green")
) def apply(color:String) = {
if(markers.contains(color)) markers(color) else null
} def getMarker(color:String) = {
if(markers.contains(color)) markers(color) else null
}
def main(args: Array[String]) {
println(Marker("red"))
// 单例函数调用,省略了.(点)符号
println(Marker getMarker "blue")
}
}

操作符即方法

  1. 前缀操作符

    只有+、-、、!有,对应的方法名是unary_+、unary_-、unary_、unary_!

    2.中缀和后缀操作符

​ 以冒号结尾的操作符,右操作符是调用对象

[2]SpinalHDL教程——Scala简单入门的更多相关文章

  1. scala简单入门_wordCount

    scala的语法写起来是非常的舒服的,相比java来说,简便许多.而Java在scala面前就显的略微有些笨重了. 接下来我们看一下scala版的wordcount import scala.io.S ...

  2. 程序员,一起玩转GitHub版本控制,超简单入门教程 干货2

    本GitHub教程旨在能够帮助大家快速入门学习使用GitHub,进行版本控制.帮助大家摆脱命令行工具,简单快速的使用GitHub. 做全栈攻城狮-写代码也要读书,爱全栈,更爱生活. 更多原创教程请关注 ...

  3. GitHub这么火,程序员你不学学吗? 超简单入门教程 【转载】

    本GitHub教程旨在能够帮助大家快速入门学习使用GitHub. 本文章由做全栈攻城狮-写代码也要读书,爱全栈,更爱生活.原创.如有转载,请注明出处. GitHub是什么? GitHub首先是个分布式 ...

  4. Flyway 简单入门教程

    原文地址:Flyway 简单入门教程 博客地址:http://www.extlight.com 一.前言 Flyway 是一款开源的数据库版本管理工具,它更倾向于规约优于配置的方式.Flyway 可以 ...

  5. BAT脚本编写教程简单入门篇

    BAT脚本编写教程简单入门篇 批处理文件最常用的几个命令: echo表示显示此命令后的字符 echo on  表示在此语句后所有运行的命令都显示命令行本身 echo off 表示在此语句后所有运行的命 ...

  6. NumPy简单入门教程

    # NumPy简单入门教程 NumPy是Python中的一个运算速度非常快的一个数学库,它非常重视数组.它允许你在Python中进行向量和矩阵计算,并且由于许多底层函数实际上是用C编写的,因此你可以体 ...

  7. lodop简单入门教程

    lodop简单入门 1 安装(这个不介绍,下载安装即可) 声明只能装windows,linux不能装,所以linux 服务器要使用直接使用http://localhost:8000/CLodopfun ...

  8. emacs最简单入门,只要10分钟

    macs最简单入门,只要10分钟  windwiny @2013    无聊的时候又看到鼓吹emacs的文章,以前也有几次想尝试,结果都是玩不到10分钟就退出删除了. 这次硬着头皮,打开几篇文章都看完 ...

  9. Springmvc整合tiles框架简单入门示例(maven)

    Springmvc整合tiles框架简单入门示例(maven) 本教程基于Springmvc,spring mvc和maven怎么弄就不具体说了,这边就只简单说tiles框架的整合. 先贴上源码(免积 ...

  10. Spring_MVC_教程_快速入门_深入分析

    Spring MVC 教程,快速入门,深入分析 博客分类: SPRING Spring MVC 教程快速入门  资源下载: Spring_MVC_教程_快速入门_深入分析V1.1.pdf Spring ...

随机推荐

  1. js数组常用的方法

    var arr=['hello','前端','world']; 1. arr.join(分隔符):将数组中的值拼接成一个字符串,返回这个字符串,默认分隔符"," arr.join( ...

  2. CentOS 安装 jdk1.8

    转自:https://www.cnblogs.com/yjlch1016/p/8900841.html 前置条件:不使用openjdk,若想使用openjdk.直接在centos下 使用 yum  查 ...

  3. Angular架构学习

    定义 Angular 是一个用 HTML 和 JavaScript 或者一个可以编译成 JavaScript 的语言(例如 Dart 或者 TypeScript ),来构建客户端应用的框架. 写 An ...

  4. 持续集成环境(2)-Jenkins插件管理

    Jenkins本身不提供很多功能,我们可以通过使用插件来满足我们的使用.例如从Gitlab拉取代码,使用 Maven构建项目等功能需要依靠插件完成.接下来演示如何下载插件. 修改Jenkins插件下载 ...

  5. 116、商城业务---分布式事务---seata的AT模式存在的问题&&最终一致性库存解锁逻辑

    seata的AT模式不适合高并发的项目,因为它需要加锁来保证回滚.因此我们的订单服务方法中就尽量不能使用@GlobalTransactional来管理分布式事务. 因此在订单服务中,我们使用下面这种方 ...

  6. Vue中 ref、$refs区别与使用

    定义2个组件: 子组件ChildrenSubRef.vue: 1 <template> 2 <div> 3 4 </div> 5 </template> ...

  7. Ubuntu 20.24 安装Postgresql 14

      1.运行环境 WSL+Ubuntu 20.04   2.安装Postgresql 进入Linux命令行,参照Postgresql官网安装指南 # Create the file repositor ...

  8. [picoCTF]Insp3ct0r write up

    根据提示,需要检查浏览器上的Web代码(动手翻译一下啦) (漫不经心的瞅瞅页面,curl+UUUUUUU(一只U就行)一下下,微微瞄一瞄,where is flag? fn+f12(或其它)打开源代码 ...

  9. switch case return return 返回不了值的原因

    我在页面写了一个ajax ,但是控制器 是 用switch case break 控制的控制器  , 我想 在case login 方法里  直接 return  , 但是不好使 始终是 null , ...

  10. 使用vite创建vue3 遇到 process is not defined

    今天新建项目遇到报错,查资料得出,需要在vite.config.js中添加代码如下 import { defineConfig } from 'vite' import vue from '@vite ...