scala-access对象字段

cnjp1d6j  于 2021-06-21  发布在  Flink
关注(0)|答案(1)|浏览(397)

有没有可能做如下的事情?

@FunctionHint(
  output = new DataTypeHint(s"is_$role BOOLEAN")
)
class Func(role: String) extends TableFunction[Boolean] {
  ...
}

注意使用 role 在注解中,它是被注解对象上的字段。

wkyowqbh

wkyowqbh1#

就像你解释的那样 @FunctionHint 是一个flink注解,如何在运行时处理它是flink的责任。看来flink不支持你想要的模板制作。
可以使用宏注解为每个角色生成具有适当运行时注解的类

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.blackbox

@compileTimeOnly("Enable macro annotations")
class generateFunc(roles: String*) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro GenerateFuncMacro.impl
}

object GenerateFuncMacro {
  def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = {
    import c.universe._
    val roles = c.prefix.tree match {
      case q"new generateFunc(..$rs)" => rs.map {
        case q"${role: String}" => role
      }
    }
    val classes = roles.map(role =>
      q"""
         @_root_.org.apache.flink.table.annotation.FunctionHint(
           output = new _root_.org.apache.flink.table.annotation.DataTypeHint(${s"is_$role BOOLEAN"})
         )
         class ${TypeName(s"Func$role")} extends _root_.org.apache.flink.table.functions.TableFunction[_root_.scala.Boolean] {
         }
      """
    )
    annottees match {
      case q"$mods object $tname extends { ..$earlydefns } with ..$parents { $self => ..$body }" :: Nil =>
        q"""$mods object $tname extends { ..$earlydefns } with ..$parents { $self =>
           ..$body
           ..$classes
        }"""
    }
  }
}

用法:

@generateFunc("Aa", "Bbb")
object Funcs

//scalac: object Funcs extends scala.AnyRef {
//  def <init>() = {
//    super.<init>();
//    ()
//  };
//  @new FunctionHint(output = new DataTypeHint("is_Aa BOOLEAN")) class FuncAa extends TableFunction[Boolean] {
//    def <init>() = {
//      super.<init>();
//      ()
//    };
//    <empty>
//  };
//  @new FunctionHint(output = new DataTypeHint("is_Bbb BOOLEAN")) class FuncBbb extends TableFunction[Boolean] {
//    def <init>() = {
//      super.<init>();
//      ()
//    };
//    <empty>
//  }
//}

所以你可以用 Funcs.FuncAa , Funcs.FuncBbb 等。

相关问题