问题描述
我正在尝试将 Nim 与 Elm 结合使用。 Elm 有一个端口系统,可以发送和接收消息,类似于网络工作者。
我在主模块中有这个代码:
import ./elm
import ./portMessages
type
State = object
elmProgram: elm.Program
portToElm: elm.SubPort[portMessages.Outgoing]
# Error is with this function
proc newState(
elmProgram: elm.Program,): State =
return State(
elmProgram: elmProgram,portToElm: elmProgram.getSubPort("rawSubscribe"),)
当我尝试编译时,我从编译器收到此错误消息:
Error: invalid type: 'SubPort[SubPort.T]' in this context: 'proc (elmProgram: Program): State' for proc
这是 elm
模块。 SubPort
类型允许通过端口发送 T
。
type
Program* {.importjs.} = ref object of JsRoot
SubPort*[T: JsRoot] {.importjs.} = ref object of JsRoot
# Get a reference to a Sub port (to Elm)
proc getSubPort*[T: JsRoot](
program: Program,name: cstring,): SubPort[T] {.importjs: "#.ports[#]".}
这是“portMessages”模块:
type
OutgoingKind* {.importjs.} = enum
portErrorPopup = 0,Outgoing* {.importjs.} = ref object of JsRoot
case kind*: OutgoingKind
of portErrorPopup:
msg*: cstring
解决方法
类型不匹配是因为 getSubPort("messages")
仍然是一个未指定的泛型,因为它的返回类型是 SubPort[T]
,无法从其参数中推断出来。
同时,您已指定您的 State
类型的成员 portToElm
的类型为 SubPort[Outgoing]
答案应该很简单:
proc newState(elmProgram: Program): State =
State(
elmProgram: elmProgram,portToElm: getSubPort[Outgoing](elmProgram,"rawSubscribe")
)
但是由于编译器错误,这仍然不起作用。解决方法是使用通用限制的概念:
在elm
中:
type
Program* {.importjs.} = ref object of JsRoot
IsJsRoot = concept type t
t is JsRoot
SubPort*[T: IsJsRoot] {.importjs.} = ref object of JsRoot
proc getSubPort*[T:IsJsRoot](
program: Program,name: cstring): SubPort[T]{.importjs: "#.ports[#]".}
(我不明白为什么 SubPort 首先需要是通用的,尤其是因为它是 importjs,但这不是重点)
,从 : JsRoot
类型的定义中删除 SubPort
:
type
# ...
SubPort*[T] {.importjs.} = ref object of JsRoot
调用portMessages.Outgoing
时还需要指定getSubPort
:
return State(
# ...
portToElm: elmProgram.getSubPort[: portMessages.Outgoing]("rawSubscribe"),)