zoukankan      html  css  js  c++  java
  • scala之旅-核心语言特性【基础】(二)

    本章将介绍scala语言的基础内容

    尝试在浏览器中使用Scala

    你可以使用ScalaFiddle在浏览器中运行Scala。这是一种简单、零基础的方式来实验Scala代码段。

    1. 访问网址 https://scalafiddle.io.
    2. 复制
      println("Hello, world!")

      进左边的面板

    3. 点击Run. 在右边的面板就会显示输出

    表达式

    表达式是可以被计算的语句:

    1+1

    你可以用 println 对表达式的结果输出:

    println(1) // 1
    println(1 + 1) // 2
    println("Hello!") // Hello!
    println("Hello," + " world!") // Hello, world!

    【注:输出结果:】

    1
    2
    Hello
    Hello, world

    你可以用关键字 val 来命名表达式的结果

    val x = 1 + 1
    println(x) //2

    【注:输出结果:】

    2

    像 x 这种用来命名结果的,我们称之为值。引用值不会重新计算表达式。

    值不能被重新定义赋值. 【注:val修饰的变量是被final修饰过了】

    x = 3 // 无法编译通过.

    值的类型描述可以被省略,编译器会自行推断出来。当然也可以显式地声明出来

    val x: Int = 1 + 1

    注意声明类型时,Int是跟在命名 x 后的,用一个 : 表示这个值的类型

    变量

    变量跟值类似,但是变量可以重新赋值定义。你可以通过 var 关键字来声明一个变量

    var x = 1 + 1
    x = 3 // 这里因为用var声明,所以可以编译通过    .
    println(x * x) // 9

    跟值一样,变量的类型也可以被省略或者被推断,也可以被显式的指定出来

    var x: Int = 1 + 1

    【注:这里解释下 scala是一个静态语言,静态语言意味着变量一旦类型定下就不可以改变。虽然变量和值都是可以通过编译器进行类型推断的,但是类型是不能被修改的。例如:

    var a = 10  //变量a 是Int类型,这是编译器推断的结果
    a = "hello"  //这里编译会报错,因为a的类型已经是Int,再重新赋予字符串时就会类型错误

    代码块

    你可以通过 {} 包围的方式来组合表达式。我们称之为代码块。

    该块的最后一个表达式的结果也是这个代码块的最终结果:

    println({
      val x = 1 + 1
      x + 1
    }) // 3

    函数

    函数是具有参数、并且能传递参数值的表达式。

    你可以定义一个匿名函数(例如 一个没有名称的函数),这个函数的作用是给一个整型的值加1

    (x: Int) => x + 1

    在 => 左边是一个参数的列表,右边则是一个包含参数的表达式

    当然你也可以命名这个函数

    val addOne = (x: Int) => x + 1
    println(addOne(1)) // 2

    一个函数可以有多个参数:

    val add = (x: Int, y: Int) => x + y
    println(add(1, 2)) // 3

    当然它也可以没有参数:

    val getTheAnswer = () => 42
    println(getTheAnswer()) // 42

    方法

    方法外观和行为都非常像函数,但是它们之间有一些细微的区别。

    方法是通过 def 关键字定义, def 后面跟着一个名字,然后紧接着一个参数列表,一个返回结果,和一个代码体

    def add(x: Int, y: Int): Int = x + y
    println(add(1, 2)) // 3

    注意方法的返回类型声明是在参数列表后面用一个 : 接起来的

    一个方法可以传递多个参数列表:

    def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier
    println(addThenMultiply(1, 2)(3)) // 9

    或者根本就没有参数列表:

    def name: String = System.getProperty("user.name")
    println("Hello, " + name + "!")

    方法和函数还有一些其他区别,但是就目前为止,你还是可以认为方法就是类似于函数的东西。

    方法也可以有多行的表达式:

    def getSquareString(input: Double): String = {
      val square = input * input
      square.toString
    }
    println(getSquareString(2.5)) // 6.25

    方法的代码体内的最后一行表达式的结果也就是方法的返回结果.(Scala有返回关键字,但是用的很少) 【注:函数和方法的都是以最后一个变量或表达式作返回结果,你可以认为就是在最后一行代码加隐式的加了一个return】

    你可以用 class 关键字定义一个类,类后面接一个参数列表 就是它的有参构造类

    class Greeter(prefix: String, suffix: String) {
      def greet(name: String): Unit =
        println(prefix + name + suffix)
    }

    greet 方法的返回结果是 Unit ,这表明这个方法没有任何返回值。 类似于Java和C中的 void。(有一个小区别是,由于Scala的每个表达式都必须返回值,因此Unit实际上也是一个单例的值,只不过这个值是 空(),不包含任何信息的值)

    val greeter = new Greeter("Hello, ", "!")
    greeter.greet("Scala developer") // Hello, Scala developer!

    我们会在后面的章节对类进行一个深入的讲解

    Case 类

    Scala有一个特殊的类,叫做 case 类。默认的情况下,case类的实例是不可变的,且它们是通过值比较的(区别与普通的类,普通的类是通过引用进行比较的)。这些特性让case 类在模式匹配中非常的有优势。

    你可以定义case类通过 case class 关键字声明:

    case class Point(x: Int, y: Int)

    你也可以不用new关键字就可以实例化一个case类对象

    val point = Point(1, 2)
    val anotherPoint = Point(1, 2)
    val yetAnotherPoint = Point(2, 2)

    case 类是通过值进行比较的,而不是通过引用

    if (point == anotherPoint) {
      println(point + " and " + anotherPoint + " are the same.")
    } else {
      println(point + " and " + anotherPoint + " are different.")
    } // Point(1,2) and Point(1,2) are the same.
    
    if (point == yetAnotherPoint) {
      println(point + " and " + yetAnotherPoint + " are the same.")
    } else {
      println(point + " and " + yetAnotherPoint + " are different.")
    } // Point(1,2) and Point(2,2) are different.

    关于case 类还有很多需要介绍,我们会在后面的章节继续深入介绍,相信你会爱上它们的

    Objects 伴生对象

    Objects 伴生对象是它们自己定义的一个单例实例。你可以把它认为是一个类自身携带的一个单例

    你可以用 object 关键字来定一个伴生对象objects

    object IdFactory {
      private var counter = 0
      def create(): Int = {
        counter += 1
        counter
      }
    }

    你可以引用对象的名称来直接访问它的内部

    val newId: Int = IdFactory.create()
    println(newId) // 1
    val newerId: Int = IdFactory.create()
    println(newerId) // 2

    我们将在后面的章节来详细介绍它

    特性 Traits

    特性是一个包含某些属性和方法的抽象数据类型。在Scala继承中,一个类只能被允许继承一个其他类,但是它可以被继承多个特性。

    你可以通过 trait 关键字来定义特性:

    trait Greeter {
      def greet(name: String): Unit
    }

    特性可以有一个默认的实现:

    trait Greeter {
      def greet(name: String): Unit =
        println("Hello, " + name + "!")
    }

    你可以使用一个 extends 关键字来继承一个特性,并且用 override 关键字来重写它的实现体

    class DefaultGreeter extends Greeter
    
    class CustomizableGreeter(prefix: String, postfix: String) extends Greeter {
      override def greet(name: String): Unit = {
        println(prefix + name + postfix)
      }
    }
    
    val greeter = new DefaultGreeter()
    greeter.greet("Scala developer") // Hello, Scala developer!
    
    val customGreeter = new CustomizableGreeter("How are you, ", "?")
    customGreeter.greet("Scala developer") // How are you, Scala developer?

    这里的 DefaultGreeter 只继承了一个特性,但实际上它可以继承多个特性。

    我们将在后面的章节深入介绍特性

    Main 方法

    main 方法是Scala程序的入口点。Java虚拟机也需要一个包含一个String数组参数的 main 方法。

    使用一个 伴生对象object,你可以像如下这样定义一个main 方法:

    object Main {
      def main(args: Array[String]): Unit =
        println("Hello, Scala developer!")
    }
  • 相关阅读:
    汉字转拼音的Java类库——JPinyin
    更改MySQL数据库的编码为utf8mb4
    mysql 添加列,修改列,删除列
    mysql解决datetime与timestamp精确到毫秒的问题
    mysql之数据库备份与恢复
    linux常用命令集锦
    如何更改linux文件目录拥有者及用户组
    linux 查找文件命令
    关于servlet中重定向、转发的地址问题
    jQuery的validation插件(验证表单插件)
  • 原文地址:https://www.cnblogs.com/zhouwenyang/p/13851134.html
Copyright © 2011-2022 走看看