我正在使用 gocql 库https://github.com/gocql/gocql连接到 cassandra。您能否帮助我如何将标志设置gocqlDebug
为true
我想要一些调试级别日志。gocqlDebug 似乎是包 private 。我如何将其设置为 true?
package main
import (
"fmt"
"strings"
"time"
)
func main() {
const col = 30
// Clear the screen by printing \x0c.
bar := fmt.Sprintf("\x0c[%%-%vs]", col)
for i := 0; i < col; i++ {
fmt.Printf(bar, strings.Repeat("=", i)+">")
time.Sleep(100 * time.Millisecond)
}
fmt.Printf(bar+" Done!", strings.Repeat("=", col))
}
第 12 行使用此格式动词语法“[%%-%vs]”。谁能解释一下它是如何解析的?双“%%”和“%vs”对我来说没有意义。谢谢。
尝试将其分成几部分并使用文字替换(例如 col 值)运行,但无法产生与运行示例所产生的结果相同的结果。
我编写 Go 一段时间了,但最近才需要实际利用 goroutine/异步操作。我很难理解事情应该如何运作。
- 我有一个 main 函数,它只是我的 cli 工具的入口点(因此它只运行 cmd.ExecuteContext() 并检查错误)。
- 我有一个命令
project doSomething
,需要在 for 循环中运行一些 go 例程。 - 我不太确定问题是什么,我已经遇到了:
fatal error: all goroutines are asleep - deadlock!
但是当我认为我已经解决了我的命令似乎永远挂起时(我认为当其中一个 go 例程遇到错误时会发生这种情况......?) 。
有人可以帮助我理解我应该在这里实现的模式吗?
主程序
func main() {
ctx := context.Background()
if err := cmd.NewRootCommand().ExecuteContext(ctx); err != nil {
log.Err(err)
os.Exit(1)
}
}
anotherfile.go
func NewRootCommand() *cobra.Command {
rootCmd.AddCommand(newProjectCmd())
return rootCmd
}
func newProjectCmd() *cobra.Command {
projCmd := &cobra.Command{
Use: "project",
Short: "Interact with groups",
}
projCmd.AddCommand(newDoSomethingCmd())
return projCmd
}
func newDoSomethingCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "doSomething",
Run: func(cmd *cobra.Command, args []string) {
// stuff happens here, but no go routines or anything.
err := project.DoSomething(cmd.Context())
if err != nil {
os.Exit(1)
}
},
}
return cmd
}
lastfile.go(项目包)
func DoSomething(ctx context.Context) error {
// lots of stuff happens
err := firstFunction(ctx)
if err != nil {
return err
}
return nil
}
func firstFunction(ctx context.Context) error {
// stuff here no go routines
err := functionWithGoRoutines(ctx)
if err != nil {
return err
}
// gets called multiple times with different parameters -- at this point I want the above to FINISH though before moving on to here
err := functionWithGoRoutines(ctx)
if err != nil {
return err
}
return nil
}
// UPDATED
func functionWithGoRoutines(ctx context.Context, items []string) error {
errors := make(chan error, 0)
var wg sync.WaitGroup
for _, item := range items {
wg.Add(1)
i := item
go func() {
defer wg.Done()
out, err := doSomethingToItemThatCanReturnError(ctx, i)
if err != nil {
errors <- fmt.Errorf("erro: %v", err)
return
}
fmt.Println(out)
}()
}
wg.Wait()
close(errors)
var err error
if len(errors) > 0 {
err = fmt.Errorf("multiple errors occurred: %v", errors)
}
return err
}
如果其他地方已经回答了这个问题而我错过了,请告诉我!据我所知,没有什么可以准确描述我的情况。如果我想做的事情有任何不清楚的地方,请告诉我!
我的最终目标是拥有一个循环遍历切片的函数,并为切片中的每个项目启动一个 go 例程。我希望每个项目的 go 例程在退出外部函数之前都有时间完成。我想收集错误(如果有)并在所有 go 例程完成后返回它们。
我还尝试在 main.go 中创建等待组,并将其一直传递到我的函数。我看到某个地方我应该在全球范围内声明它......但不确定在哪里?
更新
@Burak Sedar 解决了我最初的问题,但我意识到在我的代码中我还有一个问题/考虑因素。
上述每个 go 例程中都有另一个需要运行的 go 例程,但是这个例程不会返回错误,并且应该在后台运行,直到“外部”go 例程完成。然后就可以取消了。
我正在这样做,但它似乎接管了外部 go 例程的等待,并导致整个命令永远不会结束:
go func() {
select {
case <-ctx.Done():
return
default:
time.Sleep(30 * time.Second)
doSomethingNewThatShouldEndOnceOuterRoutineEnds(ctx)
}
return
}()
定义为:
//comparable is an interface that is implemented by all comparable types
// (booleans, numbers, strings, pointers, channels, arrays of comparable types,
// structs whose fields are all comparable types).
// The comparable interface may only be used as a type parameter constraint,
// not as the type of a variable.
type comparable interface{ comparable }
定义是什么意思?这不是一个递归接口吗?
我有一个简单的 UDP 服务器,它侦听数据包,等待 50 毫秒,就像正在执行操作一样,然后将消息打印到终端。这是服务器代码:
package main
import (
"fmt"
"log"
"log/slog"
"net"
"time"
)
func main() {
udpAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:8080")
if err != nil {
log.Fatal(err)
}
conn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
log.Fatal(err)
}
slog.Info("UDP server listening", "addr", udpAddr, "workers", numCpu)
go startWorker(0, conn)
// Block forever
<-make(chan struct{})
}
func startWorker(id int, conn *net.UDPConn) {
slog.Info("Starting worker", "id", id)
i := 0
for {
buf := make([]byte, 1024)
_, _, err := conn.ReadFromUDP(buf)
if err != nil {
slog.Error("failed to read UDP message", "err", err, "worker", id)
continue
}
time.Sleep(50 * time.Millisecond)
fmt.Print(i, " > ", string(buf))
i += 1
}
}
我有一个 go 客户端代码,它只是向该服务器发送一次字符串消息。这是客户端代码:
package main
import (
"log"
"net"
)
func main() {
udpAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:8080")
if err != nil {
log.Fatal(err)
}
conn, err := net.DialUDP("udp", nil, udpAddr)
if err != nil {
log.Fatal(err)
}
// Send a message to the server
_, err = conn.Write([]byte("Hello UDP Server\n"))
if err != nil {
log.Fatal(err)
}
}
我想测试服务器可以处理多少个数据包。所以我所做的是,我按顺序运行客户端代码 10000 次,看看将处理其中的多少个。但每次只处理大约 400-500 个数据包。这是我从终端进行测试的方法:
time (for i in $(seq 10000); do ./client; done)
没有错误日志,输出为:
real 0m12,538s
user 0m10,667s
sys 0m4,014s
我认为这可能是由于操作系统缓冲区限制而导致的问题。go startWorker(id, conn)
所以我之前在服务器代码中添加了以下代码:
// 1 GB
if err = conn.SetReadBuffer(1024 * 1024 * 1024); err != nil {
log.Fatal(err)
}
进行完全相同的测试后,处理的数据包数量变为 600-700。对于 10000 条简单的“Hello UDP Server\n”消息,1 GB 缓冲区不可能不够。谁能向我解释这种行为背后的原因以及如何解决它?
PS:我使用的是Ubuntu 22.04
我的功能是具有此签名的工作文件
func GetFileMetadata(f *multipart.FileHeader) *FileMetadata {
d := new(FileMetadata)
// ...
if typ, err := GetFileRealType(f); err == nil {
d.Type = typ.MIME.Value
fileExt = "." + typ.Extension
} else {
d.Type = "unknown"
}
return d
}
使用以下签名则不会。
func GetFileMetadata(f *multipart.FileHeader) (d *FileMetadata) {
// ...
if typ, err := GetFileRealType(f); err == nil {
d.Type = typ.MIME.Value
fileExt = "." + typ.Extension
} else {
d.Type = "unknown"
}
return
}
出现零指针取消引用错误。是什么原因?
我在 Rust 和 Go 中处理大整数时遇到了一个有趣的问题。具体来说,在处理负除数时,两种语言的除法运算结果有所不同。这是两种语言的代码:
锈
use num_bigint::BigInt;
use std::str::FromStr;
fn main() {
let n = BigInt::from_str("-4068122527548036313624952687320999183219209139149389824425650628448701979991259532638609685663741905551578447595775644964695361846038949186131821248175179900695219937607954907860922507949244416").unwrap();
let d = BigInt::from_str(
"115792089237316195423570985008687907852837564279074904382605163141518161494337",
)
.unwrap();
let res = &n / &d;
println!("res:{}", result);
}
去
package main
import "math/big"
func main() {
var n, d, res big.Int
n.SetString("-4068122527548036313624952687320999183219209139149389824425650628448701979991259532638609685663741905551578447595775644964695361846038949186131821248175179900695219937607954907860922507949244416", 10)
d.SetString("115792089237316195423570985008687907852837564279074904382605163141518161494337", 10)
res.Div(&n, &d)
println("res:", res.String())
}
输出
锈:-35132991850681684771865987637349505035135798334672277824131793024179346079627919418184483600280933255791109974931548
去:-35132991850681684771865987637349505035135798334672277824131793024179346079627919418184483600280933255791109974931549
正如您所看到的,Rust 将结果舍入为零,而 Go 将结果舍入到负无穷大。谁能解释为什么存在这种差异以及是否有办法在这种除法运算中协调这两种语言的行为?
- 我正在使用 VSCode
1.87.2
,操作系统是 Ubunu 23.10 - 使用 Go 扩展
v0.41.2
- 我出于测试目的禁用了所有其他扩展
- 使用
go1.21.0 linux/amd64
我在 Golang 文件中编写了这段代码*.go
:
switch {
case myString == "":
fmt.Println("Empty string")
case myString == "foo":
doFoo()
case myString == "bar":
fmt.Println("We got bar now!")
default:
fmt.Println("Another default")
}
VS code 将其格式化为:
switch {
case myString == "":
fmt.Println("Empty string")
case myString == "foo":
doFoo()
case myString == "bar":
fmt.Println("We got bar now!")
default:
fmt.Println("Another default")
}
问题,有没有一种方法可以合理地配置 VSCode/Go 扩展/其他(即不必编写自己的 VS Code 扩展或绕过不寻常的奇怪设置),以便保留片段 1 的格式?
我尝试过的:
- 尝试过格式化程序:
gofumpt
,gofmt
,goimports
- 尝试禁用所有扩展(除了 go)。
不知道出了什么问题。
我是 Golang 的新手,正在尝试实现其中的一些数据结构和算法,
我写了一个 go 函数,将数据添加到列表中,但由于某种原因,它进入无限循环,我已经尝试了各种方法但无济于事,而且我最终在互联网上搜索了链接列表的实际代码,并且找到了各种实现,但它们都卡在同一个地方,
我的代码
// linked-list.go
type Node struct {
data int
next *Node
}
type LinkedList struct {
head *Node
}
func (ll *LinkedList) Add(value int) {
node := &Node{
data: value,
}
if ll.head == nil {
ll.head = node
}
curr := ll.head
for curr.next != nil { // this is where the code gets stuck
curr = curr.next // this is not pointing it to the next node
}
curr.next = node
}
// main.go
func main() {
ll := modules.LinkedList{}
ll.Print()
ll.Add(1)
ll.Add(2)
ll.Print()
}
我从网上尝试的一些代码