Go语言跨平台GUI工具包tk9.0

不得不说,这名字起的.....tk9.0是一个用Go语言编写的跨平台GUI工具包,它使用Tcl/Tk作为底层图形库,无需CGo,这意味着您可以使用它来创建原生跨平台应用程序,而无需依赖于C语言编译器

优势介绍:

  • 跨平台: tk9.0支持Windows、macOS、Linux和FreeBSD等多个平台,您可以轻松地将您的应用程序移植到不同的操作系统上。
  • 无需CGo: tk9.0的实现完全使用Go语言编写,无需依赖于CGo,这意味着您不需要安装任何C语言编译器,可以轻松地将您的应用程序部署到不同的环境中。
  • 易于使用: tk9.0提供了简洁直观的API,方便您快速上手并创建自己的GUI应用程序。
  • 丰富的功能: tk9.0提供了丰富的控件,包括按钮、标签、文本框、列表框、滚动条、菜单等,可以满足您各种开发需求。
  • 高度可定制: tk9.0允许您自定义控件的外观和行为,以满足您的应用程序的特定需求。

这是一些官方示例

这些示例中写的都比较简单,并没有过多的多窗口或复杂的使用,但是常用的窗体内容的展示都有了. 开始展示

项目地址 Gitlab仓库

示例1. 图片+按钮

package main

import _ "embed"
import . "modernc.org/tk9.0"

//go:embed gopher.png
var gopher []byte

func main() {
    Pack(Label(Image(NewPhoto(Data(gopher)))),
        TExit(),
        Padx("1m"), Pady("2m"), Ipadx("1m"), Ipady("1m"))
    App.Center().Wait()
}

photo.png

示例2. 菜单

package main

import (
    "fmt"
    . "modernc.org/tk9.0"
    "runtime"
)

func main() {
    menubar := Menu()

    fileMenu := menubar.Menu()
    fileMenu.AddCommand(Lbl("New"), Underline(0), Accelerator("Ctrl+N"))
    fileMenu.AddCommand(Lbl("Open..."), Underline(0), Accelerator("Ctrl+O"), Command(func() { GetOpenFile() }))
    Bind(App, "<Control-o>", Command(func() { fileMenu.Invoke(1) }))
    fileMenu.AddCommand(Lbl("Save"), Underline(0), Accelerator("Ctrl+S"))
    fileMenu.AddCommand(Lbl("Save As..."), Underline(5))
    fileMenu.AddCommand(Lbl("Close"), Underline(0), Accelerator("Crtl+W"))
    fileMenu.AddSeparator()
    fileMenu.AddCommand(Lbl("Exit"), Underline(1), Accelerator("Ctrl+Q"), ExitHandler())
    Bind(App, "<Control-q>", Command(func() { fileMenu.Invoke(6) }))
    menubar.AddCascade(Lbl("File"), Underline(0), Mnu(fileMenu))

    editMenu := menubar.Menu()
    editMenu.AddCommand(Lbl("Undo"))
    editMenu.AddSeparator()
    editMenu.AddCommand(Lbl("Cut"))
    editMenu.AddCommand(Lbl("Copy"))
    editMenu.AddCommand(Lbl("Paste"))
    editMenu.AddCommand(Lbl("Delete"))
    editMenu.AddCommand(Lbl("Select All"))
    menubar.AddCascade(Lbl("Edit"), Underline(0), Mnu(editMenu))

    helpMenu := menubar.Menu()
    helpMenu.AddCommand(Lbl("Help Index"))
    helpMenu.AddCommand(Lbl("About..."))
    menubar.AddCascade(Lbl("Help"), Underline(0), Mnu(helpMenu))

    App.WmTitle(fmt.Sprintf("%s on %s", App.WmTitle(""), runtime.GOOS))
    App.Configure(Mnu(menubar), Width("8c"), Height("6c")).Wait()
}

苹果系统中它展示在顶部菜单栏中,并不在软件窗口里
menu.png

示例3. 文本内容

package main

import . "modernc.org/tk9.0"

func main() {
    var scroll *TScrollbarWidget
    t := Text(Font("helvetica", 10), Yscrollcommand(func(e *Event) { e.ScrollSet(scroll) }), Setgrid(true), Wrap("word"), Padx("2m"), Pady("2m"))
    scroll = TScrollbar(Command(func(e *Event) { e.Yview(t) }))
    Grid(t, Sticky("news"), Pady("2m"))
    Grid(scroll, Row(0), Column(1), Sticky("nes"), Pady("2m"))
    GridRowConfigure(App, 0, Weight(1))
    GridColumnConfigure(App, 0, Weight(1))
    Grid(TExit(), Padx("1m"), Pady("2m"), Ipadx("1m"), Ipady("1m"))
    t.TagConfigure("bgstipple", Background(Black), Borderwidth(0), Bgstipple(Gray12))
    t.TagConfigure("big", Font("helvetica", 12, "bold"))
    t.TagConfigure("bold", Font("helvetica", 10, "bold", "italic"))
    t.TagConfigure("center", Justify("center"))
    t.TagConfigure("color1", Background("#a0b7ce"))
    t.TagConfigure("color2", Foreground(Red))
    t.TagConfigure("margins", Lmargin1("12m"), Lmargin2("6m"), Rmargin("10m"))
    t.TagConfigure("overstrike", Overstrike(1))
    t.TagConfigure("raised", Relief("raised"), Borderwidth(1))
    t.TagConfigure("right", Justify("right"))
    t.TagConfigure("spacing", Spacing1("10p"), Spacing2("2p"), Lmargin1("12m"), Lmargin2("6m"), Rmargin("10m"))
    t.TagConfigure("sub", Offset("-2p"), Font("helvetica", 8))
    t.TagConfigure("sunken", Relief("sunken"), Borderwidth(1))
    t.TagConfigure("super", Offset("4p"), Font("helvetica", 8))
    t.TagConfigure("tiny", Font("times", 8, "bold"))
    t.TagConfigure("underline", Underline(1))
    t.TagConfigure("verybig", Font(CourierFont(), 22, "bold"))
    t.InsertML(`Text widgets like this one allow you to display information in a variety of styles. Display styles are controlled
using a mechanism called <bold>tags</bold>. Tags are just textual names that you can apply to one or more ranges of characters within a
text widget. You can configure tags with various display styles. If you do this, then the tagged characters will be displayed with the
styles you chose. The available display styles are:
<br><br><big>1. Font.</big> You can choose any system font, <verybig>large</verybig> or <tiny>small</tiny>.
<br><br><big>2. Color.</big> You can change either the <color1>background</color1> or <color2>foreground</color2> color, or
<color1><color2>both</color2></color1>.
<br><br><big>3. Stippling.</big> You can cause the <bgstipple>background</bgstipple> information to be drawn with a stipple fill instead
of a solid fill.
<br><br><big>4. Underlining.</big> You can <underline>underline</underline> ranges of text.
<br><br><big>5. Overstrikes.</big> You can <overstrike>draw lines through</overstrike> ranges of text.
<br><br><big>6. 3-D effects.</big> You can arrange for the background to be drawn with a border that makes characters appear either
<raised>raised</raised> or <sunken>sunken</sunken>.
<br><br><big>7. Justification.</big> You can arrange for lines to be displayed <br>left-justified <br><right>right-justified, or</right>
<br><center>centered.</center>
<br><br><big>8. Superscripts and subscripts.</big> You can control the vertical position of text to generate superscript effects like
10<super>n</super> or subscript effects like X<sub>i</sub>.
<br><br><big>9. Margins.</big> You can control the amount of extra space left on each side of the text
<br><br><margins>This paragraph is an example of the use of margins. It consists of a single line of text that wraps around on the
screen.  There are two separate left margin values, one for the first display line associated with the text line, and one for the
subsequent display lines, which occur because of wrapping. There is also a separate specification for the right margin, which is used to
choose wrap points for lines.</margins>
<br><br><big>10. Spacing.</big> You can control the spacing of lines with three separate parameters. "Spacing1" tells how much extra
space to leave above a line, "spacing3" tells how much space to leave below a line, and if a text line wraps, "spacing2" tells how much
space to leave between the display lines that make up the text line.
<br><spacing>These indented paragraphs illustrate how spacing can be used. Each paragraph is actually a single line in the text widget,
which is word-wrapped by the widget.</spacing>
<br><spacing>Spacing1 is set to 10 points for this text, which results in relatively large gaps between the paragraphs. Spacing2 is set
to 2 points, which results in just a bit of extra space within a pararaph. Spacing3 isn't used in this example.</spacing>
<br><spacing>To see where the space is, select ranges of text within these paragraphs. The selection highlight will cover the extra
space.</spacing>`)
    App.Center().Wait()
}

text.png

示例4. svg图片

package main

import . "modernc.org/tk9.0"

// https://en.wikipedia.org/wiki/SVG
const svg = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="391" height="391" viewBox="-70.5 -70.5 391 391" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect fill="#fff" stroke="#000" x="-70" y="-70" width="390" height="390"/>
<g opacity="0.8">
    <rect x="25" y="25" width="200" height="200" fill="lime" stroke-width="4" stroke="pink" />
    <circle cx="125" cy="125" r="75" fill="orange" />
    <polyline points="50,150 50,200 200,200 200,100" stroke="red" stroke-width="4" fill="none" />
    <line x1="50" y1="50" x2="200" y2="200" stroke="blue" stroke-width="4" />
</g>
</svg>`

func main() {
    Pack(Label(Image(NewPhoto(Data(svg)))),
        TExit(),
        Padx("1m"), Pady("2m"), Ipadx("1m"), Ipady("1m"))
    App.Center().Wait()
}

svg.png

示例5. 计算器

package main

import "github.com/expr-lang/expr"
import . "modernc.org/tk9.0"

func main() {
    out := Label(Height(2), Anchor("e"), Txt("(123+232)/(123-10)"))
    Grid(out, Columnspan(4), Sticky("e"))
    var b *ButtonWidget
    for i, c := range "C()/789*456-123+0.=" {
        b = Button(Txt(string(c)),
            Command(
                func() {
                    switch c {
                    case 'C':
                        out.Configure(Txt(""))
                    case '=':
                        x, err := expr.Eval(out.Txt(), nil)
                        if err != nil {
                            MessageBox(Icon("error"), Msg(err.Error()), Title("Error"))
                            x = ""
                        }
                        out.Configure(Txt(x))
                    default:
                        out.Configure(Txt(out.Txt() + string(c)))
                    }
                },
            ),
            Width(-4))
        Grid(b, Row(i/4+1), Column(i%4), Sticky("news"), Ipadx("1.5m"), Ipady("2.6m"))
    }
    Grid(b, Columnspan(2))
    App.Configure(Padx(0), Pady(0)).Wait()
}

calc.png

示例6. 字体

package main

import "fmt"
import "slices"
import . "modernc.org/tk9.0"

func main() {
    var scroll *TScrollbarWidget
    t := Text(Wrap("none"), Setgrid(true), Yscrollcommand(func(e *Event) { e.ScrollSet(scroll) }))
    scroll = TScrollbar(Command(func(e *Event) { e.Yview(t) }))
    fonts := FontFamilies()
    slices.Sort(fonts)
    Grid(t, Sticky("news"), Pady("2m"), Ipadx("1m"), Ipady("1m"))
    Grid(scroll, Row(0), Column(1), Sticky("nes"), Pady("2m"))
    GridRowConfigure(App, 0, Weight(1))
    GridColumnConfigure(App, 0, Weight(1))
    Grid(TExit(), Padx("1m"), Pady("2m"), Ipadx("1m"), Ipady("1m"))
    m := map[string]bool{}
    for i, font := range fonts {
        if m[font] {
            continue
        }
        m[font] = true
        tag := fmt.Sprintf("t%v", i)
        t.TagConfigure(tag, Font(NewFont(Family(font))))
        t.Insert("end", font+": ", "", "Lorem ipsum dolor sit amet, consectetur adipiscing elit...\n", tag)
    }
    App.Center().Wait()
}

font.png

示例7. 这个示例需要安装Gnuplot 5.4+

package main

import . "modernc.org/tk9.0"

var cm = int(TkScaling()*72/2.54 + 0.5)

func main() {
    Pack(Label(Image(NewPhoto(Width(20*cm), Height(15*cm)).Graph("set grid; splot x**2+y**2, x**2-y**2"))),
        TExit(),
        Padx("1m"), Pady("2m"), Ipadx("1m"), Ipady("1m"))
    App.Center().Wait()
}

splot.png

示例8 这个也需要安装 Gnuplot 5.4+

package main

import . "modernc.org/tk9.0"

// https://gnuplot.sourceforge.net/demo_5.4/hidden2.html
const script = `
set multiplot title "Interlocking Tori"
set title "PM3D surface\nno depth sorting"
set parametric
set urange [-pi:pi]
set vrange [-pi:pi]
set isosamples 50,20
set origin -0.02,0.0
set size 0.55, 0.9
unset key
unset xtics
unset ytics
unset ztics
set border 0
set view 60, 30, 1.5, 0.9
unset colorbox
set pm3d scansbackward
splot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) with pm3d,1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) with pm3d
set title "PM3D surface\ndepth sorting"
set origin 0.40,0.0
set size 0.55, 0.9
set colorbox vertical user origin 0.9, 0.15 size 0.02, 0.50
set format cb "%.1f"
set pm3d depthorder
splot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) with pm3d,1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) with pm3d
unset multiplot`

var cm = int(TkScaling()*72/2.54 + 0.5)

func main() {
    Pack(Label(Image(NewPhoto(Width(20*cm), Height(15*cm)).Graph(script))),
        TExit(),
        Padx("1m"), Pady("2m"), Ipadx("1m"), Ipady("1m"))
    App.Center().Wait()
}

tori.png

示例9 . 依旧要安装....

package main

import . "modernc.org/tk9.0"

// https://gnuplot.sourceforge.net/demo_5.4/surface2.9.gnu
const script = `
set dummy u, v
set key bmargin center horizontal Right noreverse enhanced autotitle nobox
set parametric
set view 50, 30, 1, 1
set isosamples 50, 20
set hidden3d back offset 1 trianglepattern 3 undefined 1 altdiagonal bentover
set style data lines
set xyplane relative 0
set title "Interlocking Tori" 
set grid
set urange [ -3.14159 : 3.14159 ] noreverse nowriteback
set vrange [ -3.14159 : 3.14159 ] noreverse nowriteback
set xrange [ * : * ] noreverse writeback
set x2range [ * : * ] noreverse writeback
set yrange [ * : * ] noreverse writeback
set y2range [ * : * ] noreverse writeback
set zrange [ * : * ] noreverse writeback
set cbrange [ * : * ] noreverse writeback
set rrange [ * : * ] noreverse writeback
set colorbox vertical origin screen 0.9, 0.2 size screen 0.05, 0.6 front  noinvert bdefault
NO_ANIMATION = 1
splot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) with lines,1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) with lines`

var cm = int(TkScaling()*72/2.54 + 0.5)

func main() {
    Pack(Canvas(Width(20*cm), Height(15*cm), Background(White)).Graph(script),
        TExit(),
        Padx("1m"), Pady("2m"), Ipadx("1m"), Ipady("1m"))
    App.Center().Wait()
}

tori_canvas.png

示例10 公式图

package main

import . "modernc.org/tk9.0"

func main() {
    tex := `$$\int _0 ^\infty {{\sin ax \sin bx}\over{x^2}}\,dx = {\pi a\over 2}$$`
    Pack(Label(Relief("sunken"), Image(NewPhoto(Data(TeX(tex, 2*TkScaling()*72/600))))),
        TExit(),
        Padx("1m"), Pady("2m"), Ipadx("1m"), Ipady("1m"))
    App.Center().Wait()
}

tex.png

示例11 文本中嵌入公式等小组件

package main

import . "modernc.org/tk9.0"
import _ "embed"

//go:embed gotk.png
var icon []byte

func main() {
    fontSize := int(10*TkScaling()/NativeScaling + 0.5)
    font := Font("helvetica", fontSize)
    var scroll *TScrollbarWidget
    t := Text(font, Height(15), Yscrollcommand(func(e *Event) { e.ScrollSet(scroll) }), Setgrid(true), Wrap("word"),
        Padx("4p"), Pady("12p"))
    scroll = TScrollbar(Command(func(e *Event) { e.Yview(t) }))
    Grid(t, Sticky("news"), Pady("2m"))
    Grid(scroll, Row(0), Column(1), Sticky("nes"), Pady("2m"))
    GridRowConfigure(App, 0, Weight(1))
    GridColumnConfigure(App, 0, Weight(1))
    Grid(Exit().Configure(font), Padx("1m"), Pady("2m"), Ipadx("1m"), Ipady("1m"))
    t.TagConfigure("c", Justify("center"))
    t.TagConfigure("e", Offset("-2p"))
    t.TagConfigure("t", Font("times", fontSize))
    sym := " <t>T<e>E</e>X</t> "
    tex := `$Q(\xi) = \lambda_1 y_1^2 \sum_{i=2}^n \sum_{j=2}^n y_i b_{ij} y_j$`
    t.InsertML(`<c>Hello Go + Tk`, NewPhoto(Data(icon)), Padx("4p"), `users!
<br><br>Hello Go + Tk +`, sym, tex, ` users! (\$inline math\$)
<br><br>Hello Go + Tk +`, sym, `$`+tex+`$`, ` users! (\$\$display math\$\$)</c>
<br><br>The above exemplifies embeding pictures and`, sym, `scripts. A text widget can also embed other widgets. For example,
when a`, Button(font, Txt("<Tbutton>")), Padx("4p"), Pady("2p"), Align("center"), `and
a`, Entry(font, Textvariable("<TEntry>"), Background(White), Width(8)), Padx("4p"), Pady("2p"), Align("center"), `are part of
the markup, they will reflow when their containing text widget is resized.`)
    App.Center().Wait()
}

embed.png

embed2.png

示例12 按钮

package main

import _ "embed"
import . "modernc.org/tk9.0"

//go:embed red_corner.png
var red []byte

//go:embed green_corner.png
var green []byte

func main() {
    StyleThemeUse("default")
    StyleElementCreate("Red.Corner.TButton.indicator", "image", NewPhoto(Data(red)))
    StyleElementCreate("Green.Corner.TButton.indicator", "image", NewPhoto(Data(green)))
    StyleLayout("Red.Corner.TButton",
        "Button.border", Sticky("nswe"), Border(1), Children(
            "Button.focus", Sticky("nswe"), Children(
                "Button.padding", Sticky("nswe"), Children(
                    "Button.label", Sticky("nswe"),
                    "Red.Corner.TButton.indicator", Side("right"), Sticky("ne")))))
    StyleLayout("Green.Corner.TButton",
        "Button.border", Sticky("nswe"), Border(1), Children(
            "Button.focus", Sticky("nswe"), Children(
                "Button.padding", Sticky("nswe"), Children(
                    "Button.label", Sticky("nswe"),
                    "Green.Corner.TButton.indicator", Side("right"), Sticky("ne")))))
    opts := Opts{Padx("1m"), Pady("2m"), Ipadx("1m"), Ipady("1m")}
    rb := TButton(Txt("Red"))
    gb := TButton(Txt("Green"))
    Grid(rb, gb, opts)
    Grid(TButton(Txt("Use style"), Command(func() {
        rb.Configure(Style("Red.Corner.TButton"))
        gb.Configure(Style("Green.Corner.TButton"))
    })), TExit(), opts)
    App.Wait()
}

tbutton.png

示例13. 类似 Bootstrap 5 的主题按钮

package main

import (
    . "modernc.org/tk9.0"
    "modernc.org/tk9.0/b5"
)

func main() {
    background := White
    primary := b5.Colors{b5.ButtonText: "#fff", b5.ButtonFace: "#0d6efd", b5.ButtonFocus: "#98c1fe"}
    secondary := b5.Colors{b5.ButtonText: "#fff", b5.ButtonFace: "#6c757d", b5.ButtonFocus: "#c0c4c8"}
    success := b5.Colors{b5.ButtonText: "#fff", b5.ButtonFace: "#198754", b5.ButtonFocus: "#9dccb6"}
    danger := b5.Colors{b5.ButtonText: "#fff", b5.ButtonFace: "#dc3545", b5.ButtonFocus: "#f0a9b0"}
    warning := b5.Colors{b5.ButtonText: "#000", b5.ButtonFace: "#ffc107", b5.ButtonFocus: "#ecd182"}
    info := b5.Colors{b5.ButtonText: "#000", b5.ButtonFace: "#0dcaf0", b5.ButtonFocus: "#85d5e5"}
    light := b5.Colors{b5.ButtonText: "#000", b5.ButtonFace: "#f8f9fa", b5.ButtonFocus: "#e9e9ea"}
    dark := b5.Colors{b5.ButtonText: "#fff", b5.ButtonFace: "#212529", b5.ButtonFocus: "#a0a2a4"}
    link := b5.Colors{b5.ButtonText: "#1774fd", b5.ButtonFace: "#fff", b5.ButtonFocus: "#c2dbfe"}
    StyleThemeUse("default")
    opts := Opts{Padx("1m"), Pady("2m"), Ipadx("1m"), Ipady("1m")}
    Grid(TButton(Txt("Primary"), Style(b5.ButtonStyle("primary.TButton", primary, background, false))),
        TButton(Txt("Secondary"), Style(b5.ButtonStyle("secondary.TButton", secondary, background, false))),
        TButton(Txt("Success"), Style(b5.ButtonStyle("success.TButton", success, background, false))),
        opts)
    Grid(TButton(Txt("Danger"), Style(b5.ButtonStyle("danger.TButton", danger, background, false))),
        TButton(Txt("Warning"), Style(b5.ButtonStyle("warning.TButton", warning, background, false))),
        TButton(Txt("Info"), Style(b5.ButtonStyle("info.TButton", info, background, false))),
        opts)
    Grid(TButton(Txt("Light"), Style(b5.ButtonStyle("light.TButton", light, background, false))),
        TButton(Txt("Dark"), Style(b5.ButtonStyle("dark.TButton", dark, background, false))),
        TButton(Txt("Link"), Style(b5.ButtonStyle("link.TButton", link, background, false))),
        opts)
    Grid(TButton(Txt("Primary"), Style(b5.ButtonStyle("focused.primary.TButton", primary, background, true))),
        TButton(Txt("Secondary"), Style(b5.ButtonStyle("focused.secondary.TButton", secondary, background, true))),
        TButton(Txt("Success"), Style(b5.ButtonStyle("focused.success.TButton", success, background, true))),
        opts)
    Grid(TButton(Txt("Danger"), Style(b5.ButtonStyle("focused.danger.TButton", danger, background, true))),
        TButton(Txt("Warning"), Style(b5.ButtonStyle("focused.warning.TButton", warning, background, true))),
        TButton(Txt("Info"), Style(b5.ButtonStyle("focused.info.TButton", info, background, true))),
        opts)
    Grid(TButton(Txt("Light"), Style(b5.ButtonStyle("focused.light.TButton", light, background, true))),
        TButton(Txt("Dark"), Style(b5.ButtonStyle("focused.dark.TButton", dark, background, true))),
        TButton(Txt("Link"), Style(b5.ButtonStyle("focused.link.TButton", link, background, true))),
        opts)
    Grid(TExit(), Columnspan(3), opts)
    App.Configure(Background(background)).Wait()
}

b5.png


不同系统下的效果展示
macOS下的效果
darwin.png

FreeBSD Xfce4
freebsd.png

Linux Mate 1.26.0
linux.png

Windows 11
windows11.png

标签: Go

相关文章

在 Go 项目中使用 LevelDB 进行数据存储

LevelDB 是一个由 Google 开发的高性能键值存储库,广泛应用于需要快速读写操作的场景。本文将介绍如何在 Go 项目中使用 LevelDB 作为数据存储,并通过示例代码展示如何初始化数...

详解Go语言依赖注入工具wire最佳实践介绍与使用

wire是一个强大的依赖注入工具,通过代码生成的方式实现了高效的依赖注入。本文详细介绍了wire的入门级和高级使用技巧,并通过示例代码展示了其强大的功能。无论是简单的依赖注入,还是复杂的依赖图生...

Go语言中copy命令讲解 切片之间复制元素

在Go语言中,copy函数是一个非常常用的内置函数,用于在切片(slice)之间复制元素。理解copy函数的用法和机制对于高效处理数据操作至关重要1. copy函数的基本用法copy函数的基本语...

深入理解 Go 语言中的 goto:用法与最佳实践

在学习编程语言时,goto 一直是一个颇具争议的概念。它常常因为“跳跃式”的行为被认为会让代码混乱且难以维护,但在 Go 语言中,goto 被保留并提供了一些实际的应用场景。今天我们将深入探讨 ...

Go并发编程与调度器及并发模式详解

Go语言以其简洁的语法和强大的并发能力,成为现代网络编程和微服务架构的热门选择。本文将深入探讨Go的并发编程模型,调度器的工作机制,以及多种并发模式的实现和应用,帮助开发者更好地理解并发编程的设...

Go语言中sync.Pool详解

sync.Pool 是 Go 语言标准库中的一个数据结构,用于提供高效的对象池。它的主要作用是缓存临时对象,以减少内存分配和垃圾回收的开销。sync.Pool 特别适合用于存储短生命周期的对象,...

图片Base64编码

CSR生成

图片无损放大

图片占位符

Excel拆分文件