在Scala.js中,如何导航地遍历对象图?

在Scala.js中,如何导航地遍历对象图?,scala,path,scala.js,scala-macros,scala-reflect,Scala,Path,Scala.js,Scala Macros,Scala Reflect,假设您希望以类似于遍历文件系统的方式遍历对象图 例如,假设您有一个支持此表达式的对象图: var x=objName.foo.bar.baz.fieldName 我们可以将此数据访问表达式编码为路径,如下所示: "objName/foo/bar/baz/fieldName" 通过将这条路径分成若干段,我们可以轻松地在JavaScript中遍历对象图,因为除了传统的点表示法外,它还支持数组访问表示法:objName[foo][bar][baz][fieldName] 在Java或JVM Scal

假设您希望以类似于遍历文件系统的方式遍历对象图

例如,假设您有一个支持此表达式的对象图:

var x=objName.foo.bar.baz.fieldName

我们可以将此数据访问表达式编码为路径,如下所示:

"objName/foo/bar/baz/fieldName"
通过将这条路径分成若干段,我们可以轻松地在JavaScript中遍历对象图,因为除了传统的点表示法外,它还支持数组访问表示法:objName[foo][bar][baz][fieldName]

在Java或JVM Scala中,我们可以使用反射来遍历对象图,但是在Scala.js环境中,如何遵循这些路径来遍历Scala对象的对象图呢


换句话说,给定一个与URI形式类似的路径,您将如何遍历Scala.js对象和字段?

您当然可以在编译时使用宏将常量字符串表示形式转换为访问器,但我想您希望能够在运行时为任意字符串执行此操作

如果目标是能够传递部分构造的路径,那么这只是传递访问器函数的问题。你可以用这样的东西使它更漂亮:

class Path[+A](private val value: () => A) {
  def resolve: A = value()
  def /[B](f: A => B): Path[B] = new Path(() => f(resolve))
}

implicit class PathSyntax[A](val a: A) extends AnyVal {
  def /[B](f: A => B): Path[B] = new Path(() => a) / f
}


object Foo {
  val bar = Bar
}

object Bar {
  val baz = Baz
}

object Baz
语法并没有那么漂亮,但它现在是类型安全的,外观也不太糟糕:

val barPath: Path[Bar.type] = Foo / (_.bar)
val bazPath: Path[Baz.type] = barPath / (_.baz)
相反,这需要更多的工作,例如路径之间没有适当的相等/比较


如果你想坚持你的方法,我不知道一个直接的解决方案。然而,我认为使用ScalaJS的全部目的是保持强类型,避免任何可能导致运行时错误的模式,如果您让编译器执行其工作,编译器本可以防止这些错误。

Scala定义的对象,还是JS定义的对象?我认为你现在会得到不同的答案,这取决于。尽管我认为在Scala 3中,这两种方式可能都是一样的。老实说,我不确定如何在Scala.js环境中为普通Scala对象执行此操作……嗨,Justin。这是关于Scala.js环境中的普通Scala对象,但是如果它不能在一般情况下用于Scala对象,您能想到一种方法来设计具有此功能的Scala类吗?