Scala编程与实践代码改变世界首页投稿(暂停使用,暂停投稿)

Scala入门笔记

2016-01-15  本文已影响1949人  Andrew_liu

本博客采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载本博客文章必须也遵循署名-非商业用途-保持一致的创作共用协议.

Scala简介

Scala 是一门多范式的编程语言, 由Martin Odersky 于2001年基于Funnel的工作开始设计Scala并于2004年正式发布

代码风格

  1. 函数和变量以小驼峰命名
  2. 类和特质以大驼峰命名
  3. 常量使用全大写命名
  4. 一般使用两格缩进
  5. Scala大部分情况可以忽略语句末尾的分号

Scala变量

Scala中尽量避免使用变量, 函数式编程的一个重要特性是不可变性(不可变变量没有副作用)

//定义一个变量
var x = 0

// 定义
val y = 1

Scala基本类型和操作

String和值类型Byte, Short, Int, Long, Float, Double, Char, Boolean

# 前缀
scala> (2.0).unary_-
res1: Double = -2.0

# 中缀
scala> x indexOf 'o'
res0: Int = 4

# 后缀
scala> val x = "Hello, World"
x: String = Hello, World
scala> x.toLowerCase
res0: String = hello, world

算术操作符: +, -, *, /, %
关系, 逻辑和位操作: >, <, >=, <=, ==, !=, &&, ||, &, |, ^, ~(反码)
位移操作: <<, >>, >>>(无符号右移)

Scala函数

函数式语言的一个主要特征是, 函数是第一类结构

函数定义如下图:

函数定义

函数式对象

object和class的区别在于: object关键字创建一个单例对象

class Rational (n: Int, d: Int) {

  //precondition
  require(d != 0)

  // 私有成员
  private val g = gcd(n.abs, d.abs)
  var numer: Int = n / g
  var denom: Int = d / g

  // auxiliary constructor, 相当于python中__init__构造函数
  def this(n: Int) = this(n, 1)
  // 函数重载
  override def toString = n + "/" + d;

  def add(other: Rational): Rational =
    new Rational(numer * other.denom + other.numer * denom, denom * other.denom)

  def -(other: Rational): Rational =
    new Rational(numer * other.denom - other.numer * denom, denom * other.denom)

  // 函数重载
  def -(i: Int): Rational =
    new Rational(numer - i * denom, denom)

  def *(other: Rational): Rational =
    new Rational(numer * other.numer, denom * other.denom)

  def lessThan(other: Rational): Boolean =
    this.numer * other.denom < other.numer * this.denom

  def max(other: Rational): Rational =
    if (lessThan(other)) other else this

  private def gcd(a: Int, b: Int): Int =
    if (b == 0) a else gcd(b, a % b)
}

var x = new Rational(1, 3);
var y = new Rational(5, 7);

println(x add y)
println(x * y)
println(x - 1)

// 隐式转换, 放在解释器方位内
implicit def intToRational(x: Int) = new Rational(x)
println(1 - x)

继承和多态

动态绑定的特性即父类指针可以指向子类对象, 通过父类指针调用成员方法时, 会查找实际所指向的对象, 然后调用对象的内的对应方法

val el: Element = new ArrayElement(Array("hello"))
val e2: ArrayElement = new LineElement("hello")

内建控制结构

表示式会产生一个值

var filename = if (!args.isEmpty) args(0) else "default.txt"


var filesList = (new File(".")).listFiles
// i <- 1 to 4(包含4), i <- 1 until 4 (不包含4)
for (file <- filesList
     if file.isFile;
     if file.getName.endsWith(".scala"))  // 过滤器使用分号隔开
    println(file)
    
var firstArg = if(args.length > 0) args(0) else ""
// 任何种类的常量和其他都可以作为case
firstArg match {
    case "text" => println("text")
    case _ => println("default")
}

// 匿名函数的写法(lambda)
scala> var someNumbers = List(1, 2, 3, 4)
scala> someNumbers.filter(x => x % 2 == 0)

// 占位符语法
scala> someNumbers.filter(_ % 2 == 0)

// 偏函数 partial funciton
scala> def sum(a: Int, b: Int, c: Int) = a + b + c
scala> val a = sum(1, _: Int, 3)
scala> a(2)

// 变长参数(Array[String])
scala> def echo(args: String*) = for(arg <- args) println(arg)
scala> echo("one")
scala> echo("one", "two")


class DefaultConstructor ( name:String , age:Int){
  def this(name:String){
    /*自定义构造器,必需首先调用默认构造器*/
    this(name , 24) ; 
  }
  def show(){
    println( name + "-->" + age ) ;
  }
}

柯里化(carry)

// 普通函数
def sum(x: Int, y: Int) = x + y

// 柯里化函数
def sum(x: Int)(y: Int) = x + y

// 实际执行
def sum(x: Int) = (y: Int) => x + y

特质(trait)

特质就像带有具体方法的java接口

特质和抽象类的区别: 抽象类主要用于有明确的父子继承关系的类树, 而特质可以用于任何类

特质定义使用trait关键字

trait Person() {
    def detail() {
        println("I'm angry!")
    }
}

// 使用extends或with混入特质, 从特质继承的方法可以像从超类继承的方法使用
class Student extends Person with Boy {
}

数据结构

package com.zhihu.antispam

参考链接

上一篇 下一篇

猜你喜欢

热点阅读