[2]SpinalHDL教程——Scala簡單入門

来源:https://www.cnblogs.com/msuad/archive/2023/04/20/17335201.html
-Advertisement-
Play Games

第一個 Scala 程式 shell裡面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 文件形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ...


第一個 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.中綴和尾碼操作符

​ 以冒號結尾的操作符,右操作符是調用對象


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單文件組件模式,即一個組件就是一個文件,但其實 Vue 也是支持使用 JSX 來編寫組件的。這裡不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速瞭解和使用 Vu ...
  • 本章目標:計算屬性是如何實現的?計算屬性緩存原理以及洋蔥模型的應用?在初始化Vue實例時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ...
  • 一、http是什麼 通俗來講,http就是電腦通過網路進行通信的規則,是一個基於請求與響應,無狀態的,應用層協議。常用於TCP/IP協議傳輸數據。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與響應:客戶端請求、服務端響應數據。 無狀態 ...
  • * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關係, * 將對象之間的通信封裝到一個中介者對象中,從而使得各個對象之間的關係更加鬆散。 * 在中介者模式中,對象之間不再直接相互交互,而是通過中介者來中轉消息。 ...
  • 他們集團的信息化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,項目投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多餘。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ...
  • 設計是一個讓人夢想成真過程,開始編碼、測試、調試之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ...
  • 作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基於此我們探索了一種新的技術體系及交付方案來解決如上問題。 ...
  • 值傳遞不會改變本身,引用傳遞(如果傳遞的值需要實例化到堆里)如果發生修改了會改變本身。 1.基本數據類型都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...