Scala中的语言特性是如何实现的(1)

从0到1,带你快速上手Scala语言 Scala,读作 “skah-lah” ,是 “Scalable Language” 的缩写,是一门多范式编程语言。它就像是编程世界里的 “变形金刚”,融合了面向对象编程(OOP)和函数式编程(FP)的特性,这意味着开发者能在同一语言中,把面向对象的设计和函数式编程的抽象结合起来使用,超级灵活!它运行在 Java 虚拟机(JVM)上,能与现有的 Java 代码无缝集成。 阅读详情

Scala可以编译为Java bytecode和CIL,从而在JVM和CLI之上运行。Scala有很多在Java和C#的世界中显得陌生的语言特性,本文将分析这些语言特性是如何实现的。

object

Scala中可以像这样创建object:

1
2
3
4
5
object HowIsObjectImplementedInScala {
  def printSomething() {
    println("printSomething")
  }
}

然后在代码的其他地方调用printSomething,一个object究竟是什么东西呢? 我们将这段Scala编译为Java bytecode,然后反编译为Java,会发现编译器为HowIsObjectImplementedInScala这个object生成了两个类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public final class HowIsObjectImplementedInScala
{
  public static void printSomething()
  {
    HowIsObjectImplementedInScala..MODULE$.printSomething();
  }
}

public final class HowIsObjectImplementedInScala$
{
  public static final  MODULE$;

  static
  {
    new ();
  }

  public void printSomething()
  {
    Predef..MODULE$.println("printSomething");
  }

  private HowIsObjectImplementedInScala$()
  {
    MODULE$ = this;
  }
}

第一个类只包含一个静态方法,其实现依赖于第二个叫做HowIsObjectImplementedInScala$的类。

HowIsObjectImplementedInScala$是一个单例,其静态块实例化自己并把this赋值给MODULE$这个public static的成员,从而可以被外界访问。

同样,我们可以把这段代码编译为CIL,然后反编译为C#:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public sealed class HowIsObjectImplementedInScala
{
  public static void printSomething()
  {
    HowIsObjectImplementedInScala$.MODULE$.printSomething();
  }
}

public sealed class HowIsObjectImplementedInScala$ : ScalaObject
{
  public static HowIsObjectImplementedInScala$ MODULE$;
  public override void printSomething()
  {
    Predef$.MODULE$.println("printSomething");
  }
  private HowIsObjectImplementedInScala$()
  {
    HowIsObjectImplementedInScala$.MODULE$ = this;
  }
  static HowIsObjectImplementedInScala$()
  {
    new HowIsObjectImplementedInScala$();
  }
}

和Java代码大同小异,除了静态构造和某几个关键字外,基本一样。一个object就是一个Scala编译器帮我们实现的singleton。

var和val

var:可变。val:不可变。关于这两个关键字何时该使用哪一个,这里不做讨论,我们只是观察这二者在编译后是如何被表示的。

这段Scala代码:

1
2
3
4
5
6
7
8
9
10
class HowAreVarAndValImplementedInScala {
  var v1 = 123
  val v2 = 456

  def method1() = {
    var v3 = 123
    val v4 = 456
    println(v3 + v4)
  }
}

定义了两个字段一个var,一个val,方法中定义了两个局部变量,一个var,一个val。

编译为Java bytecode并反编译之后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class HowAreVarAndValImplementedInScala
{
  private int v1 = 123;
  private final int v2 = 456;

  public int v1()
  {
    return this.v1;
  }

  public void v1_$eq(int x$1) { this.v1 = x$1; }

  public int v2() { return this.v2; }

  public void method1() {
    int v3 = 123;
    int v4 = 456;
    Predef..MODULE$.println(BoxesRunTime.boxToInteger(v3 + v4));
  }
}

声明为字段的v1和v2,一个是普通字段,另一个则被标记为final。编译器为v1生成了getter和setter,为v2则只有getter,因为v2作为immutable的字段是不可以被重新赋值的。

有趣的是方法中的局部变量都是普通的变量,没有被final修饰。

再来看这段Scala编译为CIL再反编译为C#之后的样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class HowAreVarAndValImplementedInScala : ScalaObject
{
  private int v1;
  private int v2;

  public override int v1()
  {
    return this.v1;
  }

  public override void v1_$eq(int x$1)
  {
    this.v1 = x$1;
  }

  public override int v2()
  {
    return this.v2;
  }

  public override void method1()
  {
    int v3 = 123;
    int v4 = 456;
    Predef$.MODULE$.println(v3 + v4);
  }

  public HowAreVarAndValImplementedInScala()
  {
    this.v1 = 123;
    this.v2 = 456;
  }
}

有一个明显的问题,v2没有标为readonly(C#世界中用于声明变量不可以重新赋值的关键字),这是compiler的bug吗?

除此之外,和Java代码一致。但是有趣的是代码中的所有public方法(包括上一段演示object的代码)都被标为了override,原因不明。

小结

本来以为研究这么简单的两个语言特性不会有啥收获,仅仅是反编译一下,看看compiler都做了啥,满足下好奇心罢了。

结果还是有意外收获,我在反编译后的代码中发现了三个有趣的问题:

  • 在Scala中被声明为val的v4为什么在反编译的Java中不是final的呢?
  • 在Scala中被声明为val的v2为什么在反编译的C#中不是readonly的呢?
  • 为什么反编译出来的C#代码中的实例级公开方法都是标有override的呢?

为什么呢?为什么呢?为什么呢?答案下期揭晓。

Scala语言的编程范式 Scala的名称来自“可扩展语言”(scalable language)这一概念,强调其设计旨在支持小型到大型的软件开发项目。它的语法简洁,类型推导机制强大,因此可以减少代码的冗余。在Scala中,程序员可以选择使用命令式、面向对象或函数式风格来构建应用,这种灵活性为其用户提供了丰富的编程体验。Scala作为一种多范式编程语言,融合了面向对象和函数式编程的优点,让开发者在解决问题时能够灵活选择最适合的方式。 阅读详情

相关推荐

如何浏览与下载全球免费的地图高分辨率(亚米级)的遥感影像?

前言 如果你想使用商业卫星的高分辨遥感影像,一般价格昂贵。我们可以使用地图平台上免费的高分辨率数据。目前数据源很多,比如说google earth、天地图、四维地球、必应地图等等。这些影像统一有一个共同点就是:RGB三波段;Web地图瓦片服务。这意味着我们可以通过瓦片服务下载影像,但下载的影像只有三个波段,分别是 一.引言 二、可使用高分辨率的地图数据源 1.Google Earth影像 2.Esri World Image 3.天地图 4.必...

锐多宝的地理空间 2万+

Scala的概述及特点

目录 一、大数据为什么学习Scala 二、Scala起源 三、Scala特点 1.面向对象 2.函数式编程 3.静态类型 4.扩展性 5.动态性 四、什么是函数式编程 函数式编程的特点: 函数式编程优势: 五、什么是静态语言和动态语言 六、什么是强类型和弱类型语言 一、大数据为什么学习Scala 1.优雅:这是框架设计师第一个要考虑的问题,框架的用户是应用开发程序员,API是否优雅直接影响用户体验。 2.速度快:Scala语言表达能力强,一行代码抵得...

CyAurora的博客 7896

告别环境配置焦虑:在Win10的Ubuntu子系统里搞定CSAPP实验环境(附32/64位库编译指南)

本文详细介绍了如何在Win10的Ubuntu子系统中搭建CSAPP实验环境,包括WSL 2的安装与配置、32/64位库的编译指南以及高效开发工具链的设置。通过优化WSL性能和使用实用技巧,开发者可以轻松应对CSAPP实验中的环境配置问题,提升学习效率。

weixin_30443813的博客 296

Scala语言的特性

简要记录了Scala语言的语法结构、变量、函数式编程、面向对象以及常用的集合类

theVicTory的博客 4604

MATLAB 2022b 用户专属:保姆级IPOPT求解器安装配置全流程(含OPTI工具箱)

本文为MATLAB 2022b用户提供IPOPT求解器的详细安装与配置指南,涵盖OPTI工具箱的适配安装、环境变量设置及常见问题解决方案。通过实战案例演示非线性优化问题的求解过程,帮助用户高效部署这一强大的优化工具,提升工程计算效率。

weixin_29092031的博客 405

本地通知与健康数据的隐私保护方案

随着移动健康(mHealth)应用的普及,本地通知与健康数据的结合为用户提供了更加个性化的健康管理体验。然而,这种便利性也带来了严峻的隐私保护挑战。本文旨在探讨如何在移动应用中实现本地通知功能的同时,确保用户健康数据的隐私安全。本地通知与健康数据结合的技术架构隐私保护的核心技术方案具体算法实现与数学模型实际应用案例分析本文首先介绍背景知识和核心概念,然后深入探讨隐私保护的技术方案,包括算法原理和数学模型。接着提供实际代码实现和应用场景分析,最后讨论未来发展趋势和挑战。

移动开发前沿的博客 1309

Scala的特征

Scala语言特征还有关于面向对象和函数式编程的相关思想

qq_53481973的博客 1183

OpenClaw 多代理协同工作模式配置指南

OpenClaw 采用。

形上得其象,形下合于数;阴阳自济,玄理自明。 1万+

Scala六大特性及常用知识点总结(一)

百度百科中对Scala这门语言的简介是这个样子:“Scala是一门多范式的编程语言,一种类似java的编程语言 ,设计初衷是实现可伸缩的语言 、并集成面向对象编程和函数式编程的各种特性。” 作为一门基于JVM的编程语言,Scala和Java在很多方面有相似之处。 Scala官网总结了它的六大特性,翻译成中文它们分别对应着以下六点: 1).Java和Scala可以混编: Scala基于JVM平台...

StandbyTheSea的博客 4759

ofd转pdf报错:org.ofdrw.reader.ZipUtil.unZipFileByApacheCommonCompress【已解决】

ofd转pdf报错:java.lang.NoClassDefFoundError:org/apache/commons/io/function/IOIterator at org.ofdrw.reader.ZipUtil.unZipFileByApacheCommonCompress,java.lang.NoSuchMethodError:org.apache.commons.compress.archivers.zip.ZipArchiveInputStream.getNextEntry()

黄团团的个人博客 1283

52、切换线性动态系统:原理、挑战与高斯和滤波解决方案

本文介绍了切换线性动态系统(SLDS)的基本原理及其在复杂时间序列建模中的应用。SLDS结合了隐马尔可夫模型的离散状态切换与线性动态系统的连续状态演化,适用于系统动态发生跳跃的场景,如化工过程监测和金融市场分析。由于精确推理在计算上不可行,文章重点阐述了高斯和滤波这一近似方法,通过有限高斯混合来逼近后验分布,并详细描述了其递归更新、权重计算与组件合并流程。同时讨论了性能评估、优化策略及常见问题的解决方案,并展望了SLDS与深度学习、在线学习和多模态融合的未来发展方向。

algae的博客 161

Scala总结(一)

程序文件的名称应该与对象名称完全匹配,保存文件时,应该保存它使用的对象名称(记住Scala是区分大小写),并追加".scala"为文件扩展名。Scala是静态编译的,所以速度会快很多,能融合到Hadoop生态圈:Hadoop现在是大数据事实标准,Spark并不是要取代Hadoop,而是要完善Hadoop生态。JVM语言大部分可能会想到Java,但Java做出来的API太丑,或者想实现一个优雅的API太费劲。这可以大幅减少名称冲突的可能性。Scala具备类型系统,通过编译时检查,保证代码的安全性和一致性。

2302_80567373的博客 1120

从数字后端角度谈谈occ电路(一)

摘要:本文介绍了芯片测试中OCC(On-Chip Clock Control)电路的设计与应用。随着工艺进步,芯片制造面临Stuck-at、Bridging和Delay等故障类型,需要不同时钟频率进行测试。OCC电路通过Clock Selection、Clock Chopping Control和Clock Gating三个模块,实现ATE时钟与PLL时钟的切换控制,支持慢速时钟检测Stuck-at故障和快速时钟检测Delay故障。文章详细解析了OCC电路结构及各模块功能,包括同步单元、移位寄存器等关键组件

芯冰乐 585

2020-10-04【学习笔记】scala语言(三十七) scala中的特质

scala中的特质 package com.learnscala4 object scala_trait { def main(args: Array[String]): Unit = { } } trait person{ //类似于java的接口 var name:String def test():Unit var age:Int=18 def test1():Unit={} } class user extends person{ override v.

qihoo233的博客 153

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

scala part1 黑马

scala是基于JVM的多范式编程语言(函数式的面向对象语言) 兼容java(可以访问java类库) 静态类型,支持类型推断和模式匹配 环境 java版本 1.8 scala版本 2.11.12(下载地址:https://www.scala-lang.org/download/2.11.12.html) IDEA 版本2020.3.2 ...

qq_40473204的博客 204

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Scala编程语言入门(1)

文章目录Scala编程语言入门Scala简介搭建开发环境安装JDK安装 Scala SDK安装IDEA的scala插件scala的REPL交互式解释器Scala语法基础scala中声明变量scala中数据类型scala中的条件表达式scala中的块表达式循环1. for循环2. while循环方法和函数1. 方法2. 函数3. 方法和函数的区别4. 方法转换为函数数组、元组、映射数组1. 定长数组2. 变长数组3. 遍历数组4. 数组常用操作元组1. 定义元组2. 示例3. 访问元组映射Map1. 不可变M

yangwei2048的博客 3万+

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

【Scala原理系列】scala中的for循环特性用法示例权威详解

本文讨论了Scala中的for循环。 第一部分介绍了语法和一些通用信息。 第二部分列出了我们可以使用该循环做什么,并给出了每个点的示例。 最后一部分提到了可以替代for循环的递归。

wang2leee的博客 2173

1:scala概述

Scala 基础摘要, Scala 跟JVM的关系

sowhat 1万+

Scala语言的算法

Scala是一种由马丁·奥德斯基(Martin Odersky)设计的编程语言,运行在Java虚拟机(JVM)上。静态类型:Scala具有强大的类型系统,能够在编译时发现类型错误。面向对象:几乎所有的东西都是对象,类和对象的封装特性帮助我们结构化代码。函数式编程:支持一等函数,允许函数作为参数传递,并且可以返回函数作为结果。高阶函数:Scala提供了丰富的集合库,可以使用高阶函数对集合执行操作。并发性:Scala的Akka框架为并发编程提供了强大的支持。

2501_90771023的博客 1348

Scala语言的循环实现

在Scala中实现循环的方式是多种多样的,从传统的for和while循环,到采用递归和高阶函数的函数式编程。在实际应用中,选择合适的循环方式可以提高代码的可读性和性能。对于编写可维护的Scala代码而言,理解这些循环结构的特性和用法是至关重要的。通过本文的学习,我们不仅掌握了Scala中循环的基本用法,还深入了解了函数式编程带来的新理念,未来在编写复杂的程序时,我们能够更灵活地运用这些知识,从而达到更优的设计与实现。

2501_90351126的博客 1010

scala语言介绍

什么是Scala scala(Scalable Language)是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性。 Scala运行于Java平台(java虚拟机上),并兼容现有的Java程序。 面向对象(将对象当作参数传来传去) + 面向函数(方法,可以将函数当作参数传来传去) 为什么要学Scala 优雅:这是框架设计师第一要考虑的 速度快 Spark就是使用Scala编写的,因此为了更好的学习Spark,需要掌握Scala这门语言 =Spark的兴起,带动Scala语言的

程序员杂谈 1万+

Scala语言的函数实现

在实际项目中,合理利用Scala的函数式编程特性,可以显著提升开发效率和代码质量,是每一位Scala开发者值得掌握的技能。在编程的世界里,函数是构建软件的基本单元之一,它不仅体现了代码的逻辑和结构,更是程序设计思想的具体体现。本文将深入探讨Scala语言中函数的实现细节,包括匿名函数、高阶函数、偏应用函数等高级概念,并通过具体示例展示它们如何提升代码的可读性和性能。这是函数式编程的核心特性之一,Scala中的map, filter, reduce等方法都是高阶函数的典型应用。一、Scala中的函数基础。

2301_81664126的博客 1101

深入浅出Scala语言:从核心特性到实战落地

摘要: Scala是一门融合面向对象与函数式编程的JVM语言,兼具Java生态兼容性与开发效率优势。本文系统介绍了Scala的核心特性:1)双模编程范式支持;2)无缝Java互操作;3)简洁语法减少样板代码;4)强大的并发处理能力;5)项目规模扩展性。文章详细讲解了环境搭建步骤,并通过基础语法、变量声明、函数式编程等核心概念展示Scala特色,强调不可变数据与函数优先的编程范式。最后提供实战案例,帮助开发者从入门到掌握Scala在大数据等领域的应用价值。

weixin_55008828的博客 1115

Scala3语言特性分类与演进解析

还在为Scala2的复杂性而头疼?面对隐式转换的魔法和宏的不稳定性感到困惑?Scala3(代号Dotty)带来了语言设计的根本性重构,旨在解决这些长期存在的痛点。本文将深入解析Scala3的语言特性分类体系,追踪其演进历程,帮助你全面掌握这一现代化编程语言的核心变革。 读完本文,你将获得: - Scala3八大特性分类的完整图谱 - 从Scala2到Scala3的迁移策略指南 - 核心语言特性的...

gitblog_01180的博客 462
上一篇: 如何一步一步推导出Y Combinator
下一篇: Scala中的语言特性是如何实现的(2)
崔鹏飞
博客等级 码龄19年 441粉丝 128原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值