Scala functions and classes

function

Function declaration

def 函数名(参数:参数类型...)[:返回值类型]{
    //方法实现
}

Standard function

def sum(x:Int,y:Int):Int={
   	return x+y
}
       等价于
def sum(x:Int,y:Int)={
    x+y
}

Scala can automatically infer the return value type. If the return value type is omitted, return must also be omitted.

Variable length parameter

def sum(values:Int*)={
    var res=0
    for(i <- values){
        res+=i
    }
    res
}
		等价于
def sum(values:Int*)={
    values.sum
}

Variable-length parameters are similar to java. They must be placed at the end of the parameter declaration and can be understood as an array.

Named parameters

def sayHello(msg:String,name:String){
    print(s"$msg~$name")
}

When assigning a parameter, you can specify the parameter name yourself to select the object to be assigned

sayHello("hello","张三")
sayHello(name="张三",msg="hello")

Parameter default value

def sayHello(msg:String="你好",name:String="张三"){
    print(s"$msg~$name")
}

The parameter default value can be given when declaring the function, and the default value can be overwritten when using it

sayHello()
sayHello("吃了吗","李四")

Built-in function

def fac(x:Int):Int={
    def mul(i:Int):Int={
        if(i>1){
            i*mul(i-1)
        }else{
            1
        }
    }
    mul(x)
}

Currying (Mastering)

Currying is to turn a function that receives multiple parameters into a function that receives a single parameter, and returns the function that receives the remaining parameters as a result.

def sum(x:Int,y:Int)={
    x+y
}
   转化为柯里化写法
def sum(x:Int)(y:Int)={
    x+y
}
sum(1)(2)
var s=sum(1)(_)                      ---返回一个函数作为结果

var s=sum _
var s1=s(1)
var s2=s1(2)
print(s2)               ---结果为3

Anonymous function|Method (emphasis)

There is no method name, only the parameter type and the return value type of the function, usually use the form of an anonymous function to declare a functional variable.

scala> var s=(x:Int,y:Int)=>{x+y}
s: (Int, Int) => Int = <function2>
scala> s(1,2)
res0: Int = 3

The def keyword can define a functional variable. You can also declare a standard method.

def sum(x:Int,y:Int):Int = {
 return x+y
}
def sum=(x:Int,y:Int)=>x+y
var sum=(x:Int,y:Int)=>x+y
var sum:(Int,Int)=> Int = (x,y)=> x+y
var sum = ((x,y)=> x+y):(Int,Int)=> Int

Through the above transformation, it can be deduced that functions can be converted into variables, so functional variables can be modified with var or val. Since
functional variables are functions, they can be modified with def.

def method(op:(Int,Int)=>Int)(x:Int,y:Int)={
 op(x,y)
}
val result01 = method((x,y)=>x+y)(1,2)
val result02 = method((x,y)=>x*y)(1,2)
println(result01)
println(result02)
def method(x:Int,y:Int,f:(Int,Int)=>Int):Int={
    f(x,y)
}
var f=(x:Int,y:Int)=>{x+y}
method(1,2,f)
结果为   3

class

Since Scala does not have static methods and static classes, static methods or static objects are defined through object.

Singleton

Singleton classes are decorated with object, and all methods declared in object are static methods, similar to the references of declared tool classes in java.

object HelloUtil {
   def main(args: Array[String]): Unit = {
    sayHello("aaa")
   }
   def sayHello(name:String):Unit={
     println("hello~ "+name)
   }
}

All methods in the singleton class are static, you can directly use the class name. Call (HelloUtil.sayHello("Zhang San"))

Singleton objects cannot be new when they are created, just assign them directly. var s=HelloUtil (generally call the method directly without creating an object)

class

class User01(){							---默认构造器,不写默认创建无参构造器(看成无参构造)
  var id:Int = _
  var name:String = _
  var age:Int = _
  def this(id:Int,name:String,age:Int){		---扩展构造器
    this()
    this.id=id
    this.name=name
    this.age=age
  }
}
var s = new User01()
var s1 = new User01
var s2 = new User01(1,"aaa",18)
print(s"${s2.id} \t ${s2.name} \t ${s2.age}")

It must be required to explicitly call this() in the first line of the construction method, where _ means that the parameter is assigned a default value

Declaration on the class (default constructor)

Once the parameters are declared on the class, when using this to declare other constructors, the constructor on the class must be called first.

Companion object (emphasis)

If the class and the object are in a scala source file, then the object User is called the companion object of the class User. The companion object can be used to easily
create the object of the class. You only need to override the corresponding apply method, as follows :

class User(var id:Int,var name:String,var age:Int) {

}
object User{
  def apply(id: Int, name: String, age: Int): User = new User(id, name, age)
}

The name of the singleton class and the class of the companion object must be the same. The method of creating the object is as follows: (apply can be omitted when using the apply method)

var user=User.apply(1,"aaa",18)     //等价于 new User(1,"aaa",18)   或者直接  User(1,"aaa",18)

It can be understood that apply is a factory method, and the function of this method is to produce objects of the class

Use the unapply method to reverse some properties in the object

def unapply(u: User): Option[(Int, String, Int)] = {
    Some((u.id,u.name,u.age))
}
var user=User(1,"aaa",18)     //等价于 new User(1,"aaa",18)
var User(id,name,age)=user
print(id+"\t"+name+"\t"+age)

Note that there can only be one unapply method in a companion object, which is different from the apply method because there can be multiple apply methods.

Abstract class abstract

There can be implemented methods and unimplemented methods in an abstract class

abstract class Animal(var name:String) {
  def eat():Unit={
    print("animal can eat")
  }
  def sleep():String
}

Interface|Trait (scala)

trait speakable {
  def speak():Unit
}
trait flyable{
  def fly():Unit
}

Inheritance and realization (emphasis)

Create a Dog object to inherit the Animal abstract class and implement the abstract methods in the trait

class Dog(name:String) extends Animal (name:String) with speakable {
  override def sleep(): String = {
    s"${name}\t在睡觉"
  }
  override def speak(): Unit = {
    print("汪 汪 汪")
  }
  override def eat(): Unit = {
    print(s"${name}\t啃骨头")
  }
}
object Dog{
  def apply(name: String): Dog = new Dog(name)
}
var dog=Dog("大黄")
dog.eat()
dog.speak()
print(dog.sleep())

Dynamic implantation of traits

If there is a Bird that inherits from Animal, you will find that this class needs to have the function of Flyable when using it:

class Bird(name:String) extends Animal(name :String) {
    override def sleep(): String = {
        "bird is sleeping"
    }
}
var bird=new Brid("小鸟") with flyable{
    override def fly(): Unit = {
        println(name + "\t飞")
    }
}
bird.fly()

You must add overwrite in the overwrite method

A class can only inherit one class with multiple traits. For example: Class A extends B with C with D{}

If only a single realization of a trait or abstract class must use extends

self

Equivalent to the this keyword, use self to alias the keyword when this is confused

class User {
    self:User =>			//:User可以省略
    var id:Int = _
    var name:String = _
    var age:Int = _
    def this( id:Int, name:String, age:Int){
        this()
        self.id=id
        self.name=name
        self.age=age
    }
}

Trait forced mixing

The following case is to require all Flyable subclasses to implement Bird interface.

trait Flyable{
    this:Bird => //可以将 该this看做成Bird类
    def fly():Unit={
        println(this.name+" 可以⻜!")
    }
}
trait Bird{
    def name:String
}
class FlyFish(n:String) extends Flyable with Bird {
    override def name= this.n
}

case class (emphasis)

Case class is like regular class, case class is used to model immutable data

case class UserCase(id:Int,name:String)         //样例类可以没有方法体的实现
val userCase1 = new UserCase(1,"aaa")
val userCase2 = UserCase(2,"bbb")
println(userCase1)
println(userCase2)
UserCase(1,aaa)
UserCase(2,bbb)

The object created by the sample class == comparison is the content. Secondly, all the attributes in the sample class are read-only and cannot be changed after assignment. They are usually used for data modeling.

val userCase2 = UserCase(2,"bbb")
var userCase3 = UserCase(2,"bbb")
println(userCase2 == userCase3)                 //true

You can simply use copy to realize the worthy transfer between two objects

var userCase3 = UserCase(2,"bbb")
var userCase4=userCase3.copy(userCase3.id,userCase3.name)
println(userCase4)

There is no inheritance relationship between case classes.

Guess you like

Origin blog.csdn.net/origin_cx/article/details/104338897