Scala学习笔记-初识函数式编程

前言

本文记录了初学Scala代码笔记以及反编译的java代码以供加深对scala代码运行过程的理解。

函数声明

scala源码


object ScalaFunction1 {
  def main(args:Array[String]):Unit={
    //类似java规范的调用形式
    println(testSum1(10, 20))   //返回30
    println(testSum2(10,20))    //返回30
    println(testSum3(10,20))    //返回()

    //与java不同的调用形式
    printScala1     //不带括号声明的只能不带括号调用
    printScala2     //带括号声明的函数可以省略括号调用
    printScala3()
  }

  //类似java规范的定义
  def testSum1(v1:Int,v2:Int):Int={  //返回值为Unit不报错,但是返回空对象(),java中不允许而scala允许
    return v1+v2
  }
  def testSum2(v1:Int,v2:Int):Int={
    v1 + v2 //return可以省略,默认返回最后一句的结果
  }
  def testSum3(v1:Int,v2:Int):Unit={  //此处不可改为int,因为println返回为空
    println(v1+v2)
  }

  //与java规范不同的函数声明
  def printScala1: Unit={//无参数可以省略括号,但是调用不可多加括号
    println("Scala")
  }
  def printScala2()={    //返回结果类型可以省略
    println("Scala")
  }
  def printScala3(){    //返回结果为空时还可以省略=
    println("Scala")
  }

}

反编译后的java代码

object编译后的字节码文件有两个,一个只是起到壳的作用,另一个是真正的执行过程。
可以看到下面这个代码中均是在调用,很显然这个代码就是所谓的壳了。

import scala.reflect.ScalaSignature;

@ScalaSignature(bytes="\006\001\005;Q!\001\002\t\002\025\tabU2bY\0064UO\\2uS>t\027GC\001\004\003%\031\007.\0319uKJ\004\024g\001\001\021\005\0319Q\"\001\002\007\013!\021\001\022A\005\003\035M\033\027\r\\1Gk:\034G/[8ocM\021qA\003\t\003\0279i\021\001\004\006\002\033\005)1oY1mC&\021q\002\004\002\007\003:L(+\0324\t\013E9A\021\001\n\002\rqJg.\033;?)\005)\001\"\002\013\b\t\003)\022\001B7bS:$\"AF\r\021\005-9\022B\001\r\r\005\021)f.\033;\t\013i\031\002\031A\016\002\t\005\024xm\035\t\004\027qq\022BA\017\r\005\025\t%O]1z!\ty\"E\004\002\fA%\021\021\005D\001\007!J,G-\0324\n\005\r\"#AB*ue&twM\003\002\"\031!)ae\002C\001O\005AA/Z:u'Vl\027\007F\002)W5\002\"aC\025\n\005)b!aA%oi\")A&\na\001Q\005\021a/\r\005\006]\025\002\r\001K\001\003mJBQ\001M\004\005\002E\n\001\002^3tiN+XN\r\013\004QI\032\004\"\002\0270\001\004A\003\"\002\0300\001\004A\003\"B\033\b\t\0031\024\001\003;fgR\034V/\\\032\025\007Y9\004\bC\003-i\001\007\001\006C\003/i\001\007\001\006C\003;\017\021\0051(A\006qe&tGoU2bY\006\fT#\001\f\t\013u:A\021\001 \002\027A\024\030N\034;TG\006d\027M\r\013\002-!)\001i\002C\001}\005Y\001O]5oiN\033\027\r\\14\001")
public final class ScalaFunction1
{
  public static void printScala3()
  {
    ScalaFunction1..MODULE$.printScala3();
  }
  
  public static void printScala2()
  {
    ScalaFunction1..MODULE$.printScala2();
  }
  
  public static void printScala1()
  {
    ScalaFunction1..MODULE$.printScala1();
  }
  
  public static void testSum3(int paramInt1, int paramInt2)
  {
    ScalaFunction1..MODULE$.testSum3(paramInt1, paramInt2);
  }
  
  public static int testSum2(int paramInt1, int paramInt2)
  {
    return ScalaFunction1..MODULE$.testSum2(paramInt1, paramInt2);
  }
  
  public static int testSum1(int paramInt1, int paramInt2)
  {
    return ScalaFunction1..MODULE$.testSum1(paramInt1, paramInt2);
  }
  
  public static void main(String[] paramArrayOfString)
  {
    ScalaFunction1..MODULE$.main(paramArrayOfString);
  }
}

真正的执行过程在一个叫做ScalaFunction1$的字节码文件中

import scala.Predef.;
import scala.runtime.BoxedUnit;
import scala.runtime.BoxesRunTime;

public final class ScalaFunction1$
{
  public static final  MODULE$;
  
  static
  {
    new ();
  }
  
  public void main(String[] args)
  {
    Predef..MODULE$.println(BoxesRunTime.boxToInteger(testSum1(10, 20)));
    Predef..MODULE$.println(BoxesRunTime.boxToInteger(testSum2(10, 20)));
    testSum3(10, 20);Predef..MODULE$.println(BoxedUnit.UNIT);
    
    printScala1();
    printScala2();
    printScala3();
  }
  
  public int testSum1(int v1, int v2)
  {
    return v1 + v2;
  }
  
  public int testSum2(int v1, int v2)
  {
    return v1 + v2;
  }
  
  public void testSum3(int v1, int v2)
  {
    Predef..MODULE$.println(BoxesRunTime.boxToInteger(v1 + v2));
  }
  
  public void printScala1()
  {
    Predef..MODULE$.println("Scala");
  }
  
  public void printScala2()
  {
    Predef..MODULE$.println("Scala");
  }
  
  public void printScala3()
  {
    Predef..MODULE$.println("Scala");
  }
  
  private ScalaFunction1$()
  {
    MODULE$ = this;
  }
}

变量声明

object ScalaVar {
  val age =10  //值不可再改变,编译后是final修饰
  def main(args:Array[String]):Unit={
    val v1 = 20 //值不可再改变,但编译后并不是final修饰
    var v2 = 30 //值可以被修改
  }
}

scala源码

object ScalaVar {
  val age =10  //值不可再改变,编译后是final修饰
  def main(args:Array[String]):Unit={
    val v1 = 20 //值不可再改变,但编译后并不是final修饰
    var v2 = 30 //值可以被修改
  }
}

反编译后的ava代码

下面还是壳

import scala.reflect.ScalaSignature;

@ScalaSignature(bytes="\006\0015:Q!\001\002\t\002\025\t\001bU2bY\0064\026M\035\006\002\007\005I1\r[1qi\026\024\b'M\002\001!\t1q!D\001\003\r\025A!\001#\001\n\005!\0316-\0317b-\006\0248CA\004\013!\tYa\"D\001\r\025\005i\021!B:dC2\f\027BA\b\r\005\031\te.\037*fM\")\021c\002C\001%\0051A(\0338jiz\"\022!\002\005\b)\035\021\r\021\"\001\026\003\r\tw-Z\013\002-A\0211bF\005\00311\0211!\0238u\021\031Qr\001)A\005-\005!\021mZ3!\021\025ar\001\"\001\036\003\021i\027-\0338\025\005y\t\003CA\006 \023\t\001CB\001\003V]&$\b\"\002\022\034\001\004\031\023\001B1sON\0042a\003\023'\023\t)CBA\003BeJ\f\027\020\005\002(U9\0211\002K\005\003S1\ta\001\025:fI\0264\027BA\026-\005\031\031FO]5oO*\021\021\006\004")
public final class ScalaVar
{
  public static void main(String[] paramArrayOfString)
  {
    ScalaVar..MODULE$.main(paramArrayOfString);
  }
  
  public static int age()
  {
    return ScalaVar..MODULE$.age();
  }
}

真正的执行过程

public final class ScalaVar$
{
  public static final  MODULE$;
  private final int age;
  
  static
  {
    new ();
  }
  
  public int age()
  {
    return this.age;
  }
  
  public void main(String[] args)
  {
    int v1 = 20;
    int v2 = 30;
  }
  
  private ScalaVar$()
  {
    MODULE$ = this;this.age = 10;
  }
}

函数引用

scala源码

object ScalaFunction2 {
  def main(args:Array[String]):Unit={
     var M = testM2 _ //引用函数
    println(M)      //<function0> 0表示无参
    println(M())    //<function0> 0表示无参
    println(M()())  //()
  }
  def testM1(): Unit ={
    println("Test M1...")
  }
  def testM2()={    //此处返回结果不可以是Unit
    testM1 _
  }
}

反编译后的ava代码

依旧是壳

import scala.Function0;
import scala.reflect.ScalaSignature;
import scala.runtime.BoxedUnit;

@ScalaSignature(bytes="\006\0019:Q!\001\002\t\002\025\tabU2bY\0064UO\\2uS>t'GC\001\004\003%\031\007.\0319uKJ\004\024g\001\001\021\005\0319Q\"\001\002\007\013!\021\001\022A\005\003\035M\033\027\r\\1Gk:\034G/[8oeM\021qA\003\t\003\0279i\021\001\004\006\002\033\005)1oY1mC&\021q\002\004\002\007\003:L(+\0324\t\013E9A\021\001\n\002\rqJg.\033;?)\005)\001\"\002\013\b\t\003)\022\001B7bS:$\"AF\r\021\005-9\022B\001\r\r\005\021)f.\033;\t\013i\031\002\031A\016\002\t\005\024xm\035\t\004\027qq\022BA\017\r\005\025\t%O]1z!\ty\"E\004\002\fA%\021\021\005D\001\007!J,G-\0324\n\005\r\"#AB*ue&twM\003\002\"\031!)ae\002C\001O\0051A/Z:u\033F\"\022A\006\005\006S\035!\tAK\001\007i\026\034H/\024\032\025\003-\0022a\003\027\027\023\tiCBA\005Gk:\034G/[8oa\001")
public final class ScalaFunction2
{
  public static Function0<BoxedUnit> testM2()
  {
    return ScalaFunction2..MODULE$.testM2();			//这里的ScalaFunction2.实际上是ScalaFunction2$,反编译失败的字符
  }
  
  public static void testM1()
  {
    ScalaFunction2..MODULE$.testM1();
  }
  
  public static void main(String[] paramArrayOfString)
  {
    ScalaFunction2..MODULE$.main(paramArrayOfString);
  }
}

真正的执行过程
···

import scala.Function0;
import scala.Predef.;
import scala.Serializable;	
import scala.runtime.AbstractFunction0;
import scala.runtime.AbstractFunction0.mcV.sp;
import scala.runtime.BoxedUnit;

public final class ScalaFunction2$
{
  public static final  MODULE$;
  
  static
  {
    new ();
  }
  
  public void main(String[] args)
  {
    Function0 M = new AbstractFunction0()
    {
public static final long serialVersionUID = 0L;
      
   public final Function0<BoxedUnit> apply()
      {
      return ScalaFunction2..MODULE$.testM2();
      }
 };
    Predef..MODULE$.println(M);
    Predef..MODULE$.println(M.apply());
    ((Function0)M.apply()).apply$mcV$sp();Predef..MODULE$.println(BoxedUnit.UNIT);
  }
  
  public void testM1()
  {
    Predef..MODULE$.println("Test M1...");
  }
  
public Function0<BoxedUnit> testM2()
  {
  new AbstractFunction0.mcV.sp()
    {
    public static final long serialVersionUID = 0L;
      
 public void apply$mcV$sp()
  {
     ScalaFunction2..MODULE$.testM1();
  }
      
   public final void apply()
      {
        apply$mcV$sp();
      }
    };
  }
  
  private ScalaFunction2$()
  {
    MODULE$ = this;
  }
}

···

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值