I am using Go 1.21.4 on a Windows 11 Pro machine and GTK 3 binding for Go.
Simple sample code:
package GTKView
import (
"github.com/gotk3/gotk3/gtk"
)
var mToolbar *gtk.Toolbar
func initGtkWidgets() {
mToolbar, _ = gtk.ToolbarNew()
}
func InitGUI(Win *gtk.Window, fp func(*gtk.TextBuffer)) {
initGtkWidgets()
mToolbar.SetHAlign(gtk.ALIGN_START)
}
This code works: InitGUI() is called from main() to initialize the GTK GUI. mToolbar is initialized with the call to initGtkWidgets() , and mToolbar.SetHAlign executes properly.
However, the following code, relying on init() to initialize mToolbar, compiles, but fails at runtime with a string of errors and memory addresses, apparently because mToolbar was not initialized by init() when InitGUI() was called from main() .
package GTKView
import (
"github.com/gotk3/gotk3/gtk"
)
var mToolbar *gtk.Toolbar
func init() {
mToolbar, _ = gtk.ToolbarNew()
}
func InitGUI(Win *gtk.Window, fp func(*gtk.TextBuffer)) {
mToolbar.SetHAlign(gtk.ALIGN_START)
}
I come from a C++ and Object Pascal background.
My understanding is that Go's `init()`
is similar to the `initialization` section of an Object Pascal unit:
Runs once, automatically, before code in the unit itself is called,
and it's possible to initialize exposed variables in the `initialization` section.
Why aren't widgets initialized properly in Go, using `init()`?
[1]: https://en.wikipedia.org/wiki/Windows_11
[2]: https://en.wikipedia.org/wiki/Embarcadero_Delphi
[3]: https://en.wikipedia.org/wiki/Object_Pascal
Thanks to Cerise Limón for pointing me in the right direction:
Package initialization
The GTK widgets are written in C, and in their constructors the widgets are initialized using pointers with the
newoperator. Although the documentation refers to initialization expressions outside ofinit(), it appears that the GTK widgets. although they are included ininit(), are also not ready for initialization because of dependencies on uninitialized variables, and were not initialized in the call toInitGUI()when relying oninit().