簡體   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