Scala的自我意识特性



我做了一个Logging trait,它封装了日志记录实现的细节,它也很好,很懒,所以效率很高,特别是当一个特定的日志级别不活跃时。

/**
* A SLF4J based logging trait 
*/
trait Log {
import org.slf4j.Logger
import org.slf4j.LoggerFactory
val loggedClazz: Class[_]
lazy val logger: Logger = LoggerFactory.getLogger(loggedClazz.getClass)
def logDebug(codeblock: => String) = {
  if (logger.isDebugEnabled) {
    logger.debug(codeblock)
  }
}
def logError(codeblock: => String) = {
  if (logger.isErrorEnabled) {
    logger.error(codeblock)
  }
}
def logInfo(codeblock: => String) = {
  if (logger.isInfoEnabled) {
    logger.info(codeblock)
  }
}
def logWarn(codeblock: => String) = {
  if (logger.isWarnEnabled) {
    logger.warn(codeblock)
  }
}
}

但是,它要求混合了这个trait的类实现以下内容:

object MyServer extends Log {
   val loggedClazz = MyServer.getClass
}

我的问题是,是否有可能以某种方式使Trait知道它被混合到哪个类中?删除需要做的:

   val loggedClazz = MyServer.getClass

解决方案:根据提供的反馈,我按照以下方式重写了类。

/**
 * A SLF4J based logging trait 
 */
trait Log {
  import org.slf4j.Logger
  import org.slf4j.LoggerFactory
  lazy val logger: Logger = LoggerFactory.getLogger(getClass)
  def logDebug(codeblock: => String) = {
    if (logger.isDebugEnabled) {
      logger.debug(codeblock)
    }
  }
  def logError(codeblock: => String) = {
    if (logger.isErrorEnabled) {
      logger.error(codeblock)
    }
  }
  def logInfo(codeblock: => String) = {
    if (logger.isInfoEnabled) {
      logger.info(codeblock)
    }
  }
  def logWarn(codeblock: => String) = {
    if (logger.isWarnEnabled) {
      logger.warn(codeblock)
    }
  }
}

完全简单。当你做对了,第一次;)

可以用val loggedClazz = getClass代替val loggedClazz: Class[_]

您当前的代码不会像预期的那样工作,因为返回的日志记录器将始终用于Class[Class[_]]类,因为您在Class[_]对象上调用getClass

用这个代替:

lazy val logger: Logger = LoggerFactory.getLogger(getClass)

您可能还想看一下SLF4S,它是SLF4J的一个薄包装器,它与您正在做的非常相似。

最新更新