【问题标题】:How to find the type of a value that has been implicitly converted?如何找到已隐式转换的值的类型?
【发布时间】:2015-06-02 09:54:25
【问题描述】:

我正在尝试将以下代码从类中提取到特征中以供重用:

import org.slf4j.{LoggerFactory, Logger}
import slick.driver.H2Driver.api._

import scala.concurrent.Await
import scala.concurrent.duration.Duration


object UserProfileFixtures {
  val logger: Logger = LoggerFactory.getLogger(UserProfileFixtures.getClass)

  val table = UserProfileQueries.query

  // todo: Create a trait for all this
  def createSchema(db: Database) = {

    logger.info("Creating schema for the UserProfiles table")
    Await.result(db.run((table.schema).create), Duration.Inf)
    logger.info("UserProfiles table schema created")
  }
}

问题是table 被隐式转换为添加schema 属性的东西。如果我只是对上面的内容进行提升和移位,table 上的隐式转换不会发生,并且编译器找不到 schema 属性。

我怎样才能知道我应该在以下 trait 中给 table 什么类型?

import org.slf4j.Logger
import slick.driver.H2Driver.api._

import scala.concurrent.Await
import scala.concurrent.duration.Duration


trait FixtureHelper {

  val logger: Logger
  val data: Seq
  val table: TableQuery[_]     // this type is wrong...

  def createSchema(db: Database) = {

    logger.info("Creating schema")
    // compiler can't resolve `schema` in the line below
    Await.result(db.run(table.schema.create), Duration.Inf)
    logger.info("Schema created")
  }
}

顺便说一句,我使用的是 slick 3.0,但这并不重要。我想知道如何在隐式转换后找出值的类型。

【问题讨论】:

    标签: scala slick slick-3.0


    【解决方案1】:

    您可以使用结构类型来获取生成的隐式类:

    scala> implicit class RchStr(s: String) { def v = 0 }
    defined class RchStr
    
    scala> implicitly[{def v: Int}]("aaa")
    res5: AnyRef{def v: Int} = RchStr@3ab71d5e //"RchStr" is implicitly inferred type here
    
    scala> implicitly[{def v: Any}]("aaa")
    res6: AnyRef{def v: Any} = RchStr@2de743a3 // you may not know type of `v` - just specify `Any` then
    
    scala> implicitly[{def z: Any}]("aaa") //there is no implicit conversions to something which has `z` member
    <console>:9: error: type mismatch;
     found   : String("aaa")
     required: AnyRef{def z: Any}
                  implicitly[{def z: Any}]("aaa")
                                           ^
    

    在这里,我需要使用 {def v: Int} 方法对任何内容进行一些隐式转换。在您的具体情况下,它应该类似于:

    println(implicitly[{def schema: Any}](table).getClass())
    

    如果您需要找出 table 的初始类型,您可以使用 table.getClass 或检查 scaladoc 以获取隐式推断的 table 的类型以进行隐式转换。

    IntelliJ IDEA 还显式地向您显示(Cntrl + 鼠标悬停)推断类型。您可能还需要检查推断类型的一些超类型。

    也可能有帮助:Showing inferred types of Scala expressionsInferred type in a Scala program

    这将为您提供确切类型的类型标记,可以使用schema 隐式转换为某些内容:

    import scala.reflect.runtime.universe._
    def typeOf[T](x:T)( implicit tag: TypeTag[T], conversion: T => {def schema: Any} ) = tag
    println(typeOf(table))
    

    【讨论】:

    • 好的,它给了我:slick.profile.RelationalProfile$TableQueryExtensionMethods。很抱歉成为一个完全的业余爱好者,但我需要给什么类型的“桌子”才能工作?我试过用点替换 $ 符号,并使用方括号,但 Intellij 仍然无法解决它。
    • 好的,所以我知道我必须使table 类型为slick.profile.RelationalProfile$TableQueryExtensionMethods,但语法是什么?我似乎无法引用嵌套类。
    • 哦,我需要用#替换$。
    • ... 现在找不到 table.schema 的 create 属性 :-( 我将开始一个新问题。
    猜你喜欢
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    相关资源
    最近更新 更多