繁体   English   中英

scalajs范围内的对象与js.global范围内的* same *对象之间有什么区别?

[英]What's the difference between object in scalajs scope and *same* object in js.global scope?

我正在尝试编写一个简单的示例以使用THREEJS lib渲染多维数据集。

package three

import org.scalajs.dom

import scala.scalajs.js
import scala.scalajs.js.Dynamic._
import scala.scalajs.js.annotation.JSName

object THREE extends js.Object
{
  @JSName ("THREE.Scene")
  class Scene extends js.Object
  {
       def add(obj: js.Object) = ???
  }

  @JSName ("THREE.Vector3")
  class Vector3(var x:js.Number, var y:js.Number, var z:js.Number) extends js.Object

  @JSName ("THREE.PerspectiveCamera")
  class PerspectiveCamera(a:js.Number,b:js.Number,c:js.Number,d:js.Number) extends js.Object
  {
    var position:Vector3 = _
  }

  @JSName ("THREE.WebGLRenderer")
  class WebGLRenderer(params:js.Dynamic) extends js.Object
  {
    def render(scene:js.Object, camera:js.Object) = ???
  }

  @JSName ("THREE.WebGLRenderer")
  class SimpleWebGLRenderer() extends js.Object
  {
    def render(scene:js.Object, camera:js.Object) = ???
    var domElement : js.Dynamic = _
  }

  @JSName ("THREE.BoxGeometry")
  class BoxGeometry(a:js.Number,b:js.Number,c:js.Number) extends js.Object

  @JSName ("THREE.MeshBasicMaterial")
  class MeshBasicMaterial(params:js.Dynamic) extends js.Object

  @JSName ("THREE.MeshBasicMaterial")
  class SimpleMeshBasicMaterial() extends js.Object

  @JSName ("THREE.Mesh")
  class Mesh(geometry:js.Object, material:js.Object) extends js.Object

}


object ThreeExample
{
  def render() =
  {
    val scene = new THREE.Scene()
    val camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000);
    val renderer = new THREE.WebGLRenderer(js.Dynamic.literal(
      canvas = global.document.getElementById("ThreeCanvas")
    ));
    val geometry = new THREE.BoxGeometry(1,1,1);
    val material = new THREE.SimpleMeshBasicMaterial()
    camera.position.z = 2;
    val cube = new THREE.Mesh(geometry, material);

现在有趣的部分。 如果我尝试写

scene.add(cube);
renderer.render(scene, camera);

我懂了

ScalaJS.c.jl_ClassCastException {s $ 1:“ [object Object]不是scala.runtime.Nothing $的实例”,e $ 1:null,stackTrace $ 1:null,stackdata:TypeError,构造函数:function…}

错误。 如果我尝试

global._scene = scene
global._cube = cube
global._camera = camera
global._renderer = renderer

global._scene.add(global._cube)
global._renderer.render(global._scene, global._camera);

一切都正确呈现,没有错误。 我的意思是,有什么收获? global._scene和scene或global._scene.add和scene.add之间有区别吗?

详细说明一下:基本上没有区别。 静态类型化接口只是与动态类型化接口所使用的相同机制的类型化外观。 但是,由于它是静态的,因此它将对您调用的方法返回的值添加检查。

在您的情况下,在调用renderer.render() ,编译器会添加一个检查,以确保此JavaScript方法返回的值实际上符合WebGLRenderer.render()的静态结果类型。 但是这种结果类型是什么? Nothing 这是为什么? 因为此方法的主体是??? ,其类型为Nothing ,因此scalac推断该方法的结果类型为Nothing 然后检查失败,因为JavaScript的render返回的值不是Nothing类型(显然,因为没有值具有该类型),这导致ClassCastException

您想要的显然不是Nothing ,而是Unit 因此,您要做的就是使用: Unit明确显示此结果类型:

def render(scene:js.Object, camera:js.Object): Unit = ???

通常,您应该始终在Facade类型中明确指定方法的结果类型,因为否则将它们推断为Nothing ,这不是您想要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM