我在 Windows 11 Pro 机器上使用 Go 1.21.4,并为 Go 绑定 GTK 3。
简单示例代码:
package GTKView
import (
"github.com/gotk3/gotk3/gtk"
)
var mToolbar *gtk.Toolbar
var aBox *gtk.Box
func initGtkWidgets() {
mToolbar, _ = gtk.ToolbarNew()
aBox, _ = gtk.BoxNew(1, 5)
}
func InitGUI(Win *gtk.Window, fp func(*gtk.TextBuffer)) {
initGtkWidgets()
mToolbar.SetHAlign(gtk.ALIGN_START)
mToolbar.SetVAlign(gtk.ALIGN_START)
aBox.PackEnd(mToolbar, true, true, 2)
Win.Add(aBox)
}
InitGUI()
从main()
调用来初始化GTK GUI。代码运行良好;小部件通过调用 initGtkWidgets()
进行初始化。
但是,以下代码依靠
init()
来初始化小部件,可以编译,但在运行时失败,并出现一串错误和内存地址,显然是因为小部件从未由 init()
初始化,或者超出了范围。 InitGUI()
被称为:
package GTKView
import (
"github.com/gotk3/gotk3/gtk"
)
var mToolbar *gtk.Toolbar
var aBox *gtk.Box
func init() {
mToolbar, _ = gtk.ToolbarNew()
aBox, _ = gtk.BoxNew(1, 5)
}
func InitGUI(Win *gtk.Window, fp func(*gtk.TextBuffer)) {
mToolbar.SetHAlign(gtk.ALIGN_START)
mToolbar.SetVAlign(gtk.ALIGN_START)
mToolbar.Add(buttonT1)
aBox.PackEnd(tv, true, true, 2)
aBox.PackEnd(mToolbar, true, true, 2)
Win.Add(aBox)
}
我有 C++ 和 Delphi 背景。我的理解是,Go 的
init()
类似于 Object Pascal 单元的初始化部分:在调用单元本身的代码之前自动运行,并且可以在初始化部分初始化公开的变量。
为什么在 Go 中使用
init()
无法正确初始化小部件?
感谢Cerise Limón为我指明了正确的方向:
更准确地说,包级变量被认为已准备好 初始化(如果尚未初始化并且没有) 初始化表达式或其初始化表达式没有 对未初始化变量的依赖。
GTK 小部件是用 C 编写的,在其构造函数中,小部件使用指针和
new
运算符进行初始化。因此,由于依赖于未初始化的变量,GTK 小部件尚未准备好初始化,,并且在依赖 InitGUI()
来初始化它们时,在调用 init()
时不可用。