美文网首页
7. Dynamic Invocation专题

7. Dynamic Invocation专题

作者: 逸章 | 来源:发表于2020-09-22 17:30 被阅读0次

一、例一

import scala.language.dynamics

class DynamicPerson extends Dynamic
{
    //selectDynamic:创建字段或方法
    def selectDynamic(key: String) = //s"what you want is : $key"
  {
    if(key.equalsIgnoreCase("name") )"your name is XXXXXXXX"
    else s" your want to get $key , but it's not allowed"
  }
}

val person = new DynamicPerson()

//可以认为动态生成一个 Name字段,它的结果是一个字符串
println(person.Name) // 输出结果 :"what you want is : Name"
println(person.age) //输出为"what you want is : age"
class D2 extends Dynamic
{
    //为了更清晰,我们更倾向于在DynamicPerson内部维护一个Map,里面可以保存属性和属性的值,或者是方法名和方法的引用
    private val fields = scala.collection.mutable.HashMap.empty[String, Any]
    //获取key对应的value值
    def selectDynamic(key: String) = fields(key)
    //更新key对应的value值
    def updateDynamic(key: String)(args: Any): Unit =
    {
        fields(key) = args;
    }
}

//------

val p = new D2
p.Age = 30
p.Name = "Mike"
//上面对 Age 和 Name 的赋值操作,就是通过 updateDynamic 完成的
println("%s is %d years old".format(p.Name,p.Age))
class DynamicPerson extends Dynamic
{
  type CallFun = Int => String
  private val fields =mutable.HashMap.empty[String,Any]
  private val functions =mutable.HashMap.empty[String,CallFun]

  //选取对象
  def selectDynamic(key:String) = fields(key)

  /**
  更新key对应的value
  这里做了一个判断,如果key以call字符串开头,我们认为是args是CallFun类型
   */
  def updateDynamic(key: String)(args: Any): Unit =
  {
    args match {
      case x if key.startsWith("call") => functions(key) = x.asInstanceOf[CallFun]
      case _ => fields(key) = args
    }
  }

  //这个就是用来动态执行方法的
  def applyDynamic(key: String)(arg:Int) =
  {
    println(functions(key)(arg))
  }
}

val p3 = new DynamicPerson()
//设置Name属性
p3.Name = "Mike"
//定义一个 call 方法
p3.call = (age:Int) => s"${p3.Name} 今年 $age 岁"
//通过 applyDynamic 执行 call 方法
p3.call(80)  //这句代码将打印出:"Mike 今年 80 岁"

二、例二

import scala.language.dynamics

class DynamicPerson extends Dynamic
{
  def selectDynamic(key:String):Any = {
    println(s"field '$key' selected")
  }
  def updateDynamic(key:String)(args:Any) = {
    println(s"field '$key' update with value '$args'")
  }

  def applyDynamic(name:String)(args:Any) = {
    println(s"method '$name' called with argument $args")
  }

  def applyDynamicNamed(name: String)(args: (String, Any)*) = {
  //注意分隔符', '
    println(s"method '$name' called with arguments ${args.mkString("'", "', '", "'")}")
  }
}
object A {
  def main (args:Array[String]): Unit = {
    val person = new DynamicPerson
    person.name
    person.age = 23
    person.sayHello("hello, world.")
    person.salary(pay = 123, time = 30)
  }
}

输出结果为:

field 'name' selected
field 'age' update with value '23'
method 'sayHello' called with argument hello, world.
method 'salary' called with arguments '(pay,123)', '(time,30)'
上面的mkString的说明: image.png

相关文章

网友评论

      本文标题:7. Dynamic Invocation专题

      本文链接:https://www.haomeiwen.com/subject/utawyktx.html