You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Nim开发版编译NimQml项目时出现‘cannot bind another =destroy’错误

Nim 开发版编译 NimQml QObject 示例时出现析构器重复绑定错误

问题详情

基于NimQml官方文档的example3(用于定义QObjects)做试验时,使用2022年11月13日的Nim开发版(后续将发布为Nim 2)编译项目,触发如下错误:

.../src/playground.nim(4, 1) template/generic instantiation of QtObject from here
.../src/playground.nim(15, 8) Error: cannot bind another '=destroy' to: Contact:ObjectType; previous declaration was constructed here implicitly: .../src/playground.nim(9, 5)

但使用Nim 1.6.8编译该项目可正常运行,此前用该开发版编译数十个依赖项目均保持了向后兼容性,不清楚为何出现此析构器相关问题。

参考代码:

import NimQml

QtObject:
  type Contact* = ref object of QObject
    m_name: string

  proc delete*(self: Contact) =
    self.QObject.delete

  proc setup(self: Contact) =
    self.QObject.setup

  proc newContact*(): Contact =
    new(result, delete)
    result.m_name = "InitialName"
    result.setup

  proc getName*(self: Contact): string {.slot.} = ## <-- 报错行
    result = self.m_name

  proc nameChanged*(self: Contact, name: string) {.signal.}

  proc setName*(self: Contact, name: string) {.slot.} =
    if self.m_name == name:
      return
    self.m_name = name
    self.nameChanged(name)

  QtProperty[string] name:
    read = getName
    write = setName
    notify = nameChanged

原因分析

Nim 2对析构器的处理规则进行了调整:ref object类型会自动生成隐式的=destroy析构器;而你手动定义的delete proc,在NimQml的QtObject模板处理中会被映射为=destroy,两者冲突导致报错。Nim 1.6.8的析构器规则更宽松,不会触发该冲突。

解决方法

NimQml的QtObject模板已封装了QObject的销毁逻辑,无需手动实现delete proc,直接移除相关代码即可:

修改后的代码:

import NimQml

QtObject:
  type Contact* = ref object of QObject
    m_name: string

  proc setup(self: Contact) =
    self.QObject.setup

  proc newContact*(): Contact =
    new(result)
    result.m_name = "InitialName"
    result.setup

  proc getName*(self: Contact): string {.slot.} =
    result = self.m_name

  proc nameChanged*(self: Contact, name: string) {.signal.}

  proc setName*(self: Contact, name: string) {.slot.} =
    if self.m_name == name:
      return
    self.m_name = name
    self.nameChanged(name)

  QtProperty[string] name:
    read = getName
    write = setName
    notify = nameChanged

内容的提问来源于stack exchange,提问作者Philipp Doerner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:30:54