Golang变量问题解析与常见解决方案

Golang变量问题解析与常见解决方案 我创建了一个全局变量,用于读取和操作图像。但有一个问题。我无法更改变量。Println函数对该变量返回nil。我感到非常困惑。

package main

import (
	"fmt"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/storage"
)

var img *canvas.Image

func main() {
	a := app.New()
	w := a.NewWindow("GoShopy")
	w.Resize(fyne.NewSize(600, 600))
	w.SetMaster()
	w.CenterOnScreen()
	save := fyne.NewMenuItem("Save", nil)
	quit := fyne.NewMenuItem("Quit", nil)
	brightness := fyne.NewMenuItem("Brightness", nil)
	contrast := fyne.NewMenuItem("Contrast", nil)
	gamma := fyne.NewMenuItem("Gamma", nil)
	saturation := fyne.NewMenuItem("Saturation", nil)
	open := fyne.NewMenuItem("Open", func() {
		file_Dialog := dialog.NewFileOpen(
			func(uc fyne.URIReadCloser, _ error) {
				img = canvas.NewImageFromFile(uc.URI().Name())
				img.FillMode = canvas.ImageFillContain
				img.SetMinSize(fyne.NewSize(600, 600))
				content := container.NewHBox(img)
				w.SetContent(content)
				w.Show()
			}, w)
		file_Dialog.SetFilter(
			storage.NewExtensionFileFilter([]string{".jpeg", ".jpg"}))
		file_Dialog.Show()
	})
	fmt.Println(img) // returns nil
	NewMenu1 := fyne.NewMenu("File",
		open, save, quit)
	NewMenu2 := fyne.NewMenu("Colors",
		brightness, contrast, gamma, saturation)
	menu := fyne.NewMainMenu(NewMenu1, NewMenu2)
	w.SetMainMenu(menu)
	w.ShowAndRun()
}


更多关于Golang变量问题解析与常见解决方案的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我不熟悉 fyne,但在我看来,设置 img 的代码直到通过菜单打开文件时才会运行,因此在构建菜单时,fmt.Println 会显示 nil。尝试将 fmt.Println 调用移到加载图像的函数中。

更多关于Golang变量问题解析与常见解决方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题出在代码执行顺序上。fmt.Println(img) 在文件对话框回调函数执行之前就被调用了,此时 img 尚未被赋值。

以下是修正后的代码:

package main

import (
	"fmt"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/storage"
)

var img *canvas.Image

func main() {
	a := app.New()
	w := a.NewWindow("GoShopy")
	w.Resize(fyne.NewSize(600, 600))
	w.SetMaster()
	w.CenterOnScreen()
	
	save := fyne.NewMenuItem("Save", nil)
	quit := fyne.NewMenuItem("Quit", nil)
	brightness := fyne.NewMenuItem("Brightness", nil)
	contrast := fyne.NewMenuItem("Contrast", nil)
	gamma := fyne.NewMenuItem("Gamma", nil)
	saturation := fyne.NewMenuItem("Saturation", nil)
	
	open := fyne.NewMenuItem("Open", func() {
		file_Dialog := dialog.NewFileOpen(
			func(uc fyne.URIReadCloser, _ error) {
				if uc == nil {
					return
				}
				
				img = canvas.NewImageFromFile(uc.URI().Name())
				img.FillMode = canvas.ImageFillContain
				img.SetMinSize(fyne.NewSize(600, 600))
				
				fmt.Println("Image loaded:", img) // 在这里打印
				
				content := container.NewHBox(img)
				w.SetContent(content)
				w.Show()
			}, w)
		file_Dialog.SetFilter(
			storage.NewExtensionFileFilter([]string{".jpeg", ".jpg"}))
		file_Dialog.Show()
	})
	
	// 初始时为nil,这是正常的
	fmt.Println("Initial img:", img)
	
	NewMenu1 := fyne.NewMenu("File",
		open, save, quit)
	NewMenu2 := fyne.NewMenu("Colors",
		brightness, contrast, gamma, saturation)
	menu := fyne.NewMainMenu(NewMenu1, NewMenu2)
	w.SetMainMenu(menu)
	
	w.ShowAndRun()
}

关键修改:

  1. fmt.Println(img) 移到文件对话框的回调函数内部,这样只有在图像实际加载后才会打印
  2. 添加了 if uc == nil 检查,防止用户取消选择文件时出现错误
  3. 在初始化时打印 img 显示其初始状态为 nil

如果需要在整个程序中访问和修改 img 变量,可以创建一个函数来更新它:

func updateImage(newImg *canvas.Image) {
	img = newImg
	fmt.Println("Image updated:", img)
}

然后在回调函数中调用:

updateImage(canvas.NewImageFromFile(uc.URI().Name()))

这样就能确保 img 变量在图像加载后被正确赋值,并且可以在程序的其他部分访问和修改。

回到顶部