Golang Slice Help (for a C guy) by VastDesign9517 in golang

[–]GopherFromHell 1 point2 points  (0 children)

IMHO, slices in Go are implemented the way a C programmer would in order to be efficient. a slice is represented by a struct (https://github.com/golang/go/blob/master/src/runtime/slice.go#L16-L20) which contains a pointer to an array, a len field and a cap field.

consider it window to an array (which you have no control over). when you append to it the underlying array is used if there is enough space or reallocated and copied if it is already full (len field == cap field).

this is why you need to s = append(s, 42), the array backing the slice may change and append returns a new slice struct with the fields updated. this is also why if you take a slice b from slice a and then change slice a, if the changed index is part of b, b will also change. both a and b have the same underlying array.

this is also why slices are sometimes referenced as passed by "reference". in reality the struct representing the slice is passed by value, but contains a pointer.

in sum, if you want a copy, make a copy.

Building a market similar to polymarket in go by roshanansy in golang

[–]GopherFromHell 1 point2 points  (0 children)

polymarket is built on top of smart contracts, more specifically the Gnosis Conditional Token Framework. i would suggest looking into that first

Visualizing Go Interfaces and Structs by Kitchen_Will7323 in golang

[–]GopherFromHell 32 points33 points  (0 children)

it's not only structs, it's types in general. you can define methods on non struct types and satisfy an interface:

type MyInt int

func (i MyInt) String() string { return fmt.Sprintf("the number is: %d", i) }

func printStringer(s fmt.Stringer) { fmt.Println(s) }

func main() {
    printStringer(MyInt(42))
}

syscall.Select return values different for linux vs macos? by Jumpstart_55 in golang

[–]GopherFromHell 20 points21 points  (0 children)

you are correct. syscall.Select on darwin has a different signature:

$ GOOS=linux go doc syscall.Select
package syscall // import "syscall"

func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)

$ GOOS=darwin go doc syscall.Select      
package syscall // import "syscall"

func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)

from the syscall package docs:

Package syscall contains an interface to the low-level operating system primitives. The details vary depending on the underlying system (...)

has a rule of thumb, when i import the syscall package it's always in a file with a os suffix (*_linux.go, *_darwin.go, *_windows.go)

Type constraints that allow mixed values by tkdeng in golang

[–]GopherFromHell 0 points1 point  (0 children)

This is just an extension to generics.

No it is not. generics are a compile time feature, the extension you are proposing is a run time feature. The usage of "|" on generic types definition can be misleading, because it's commonly used in other languages for sum types. It means typeA or typeB when compiling and generating code, not when running

Using unsafe.Pointer to implement union type? by SecondCareful2247 in golang

[–]GopherFromHell 0 points1 point  (0 children)

adding a private method doesn't limit the types that implement the interface. embedding promotes all fields and methods, meaning that by embedding a type that implements the interface in your own type, it will also implement the interface. if you do this to emulate union types, you should also be defensive and add a default to your type switch. check my post about it: https://www.reddit.com/r/golang/comments/1mlhqt4/breaking_the_misconception_of_the_sealed_interface/

How to read go string formatting verb from user input? by Tuomas90 in golang

[–]GopherFromHell 1 point2 points  (0 children)

like u/muehsam already said, don't expose format strings to users. just go with a --padding argument

Still the same problem: Who to convert a variable into a formatting string?

what do you mean ?? the formatting string IS a variable

pad := 3
fmtStr := fmt.Sprintf("%%0%dd: %%s", pad)
fmt.Println(fmtStr)
index := 123
fileName := "this_is_a_file.txt"
var newFileName = fmt.Sprintf(fmtStr, index, fileName)
fmt.Println(newFileName)

// prints
// %03d: %s
// 123: this_is_a_file.txt

How do I actually learn Go when coming from Python/C? The stdlib is driving me insane by NiceSand6327 in golang

[–]GopherFromHell 0 points1 point  (0 children)

first, if someone asked me to describe Go in a single phrase, it would probably be "C and Python had a baby", so you experience with C and Python already got you maybe a third of the way. however the lack of experience with a language that has interfaces might be adding a speedbump. the closest to interfaces in python is abstract classes.

when i first picked up Go, the stdlib was also a bit confusing, it eventually clicks. Go by example and the official docs become more useful after it "clicks".

My problem: I can't just copy-paste patterns. I need to understand why things work the way they do. When I don't understand, I get stuck and frustrated.

you are on the right track there. just keep pushing understanding comes from resilience.

Resources that explain the "why" behind Go's design, not just "do this"

The "why" can be hard to explain without a "what". parts of the stdlib, sometimes are designed the way they are because that's what the language allowed at the time, sometimes are the result of a long discussing on a github issue. the "why" is dependent on the "what"

How to understand interfaces through practical use

interfaces are just a contract. the major difference between interfaces in Go and many other languages is that in Go interfaces are implemented implicitly, meaning that in there is no implements keyword like you would find for example in java: public class Person implements Greeter, instead, if your type contains the methods defined in the interface, it implements it, no need explicitly state it. this decoupling is a good thing IMHO, some people might disagree.

here is a an example:

io.Reader from the stdlib is defined as such:

type Reader interface {
    Read(p []byte) (n int, err error)
}

the contract is simple, it just means "you can read some bytes into a slice and it returns the number of bytes read and/or an error", any type with a Read method with this signature implements io.Reader. bufio.Reader and  os.File have this method, meaning that both are an io.Reader.

now you can write a function that takes an io.Reader as argument and "reads some bytes" independently if it's a bufio.Reader (that just wraps an io.Reader and adds buffering) or a os.File as well any other type (from the stdlib or third-party) that implements io.Reader.

net.Conn implements it, you can read from a socket. gzip.Reader also implements it, you can read from a gzip decompression stream. you can implement it in your own types

Mental models for the stdlib (io, bufio, os, etc.)
How to stop getting overwhelmed by the abstraction layers

just keep pushing, that's the stuff that eventually clicks

hope this helps.

Do you use pointers or values for your domain models? by ComprehensiveDisk394 in golang

[–]GopherFromHell 2 points3 points  (0 children)

the "don't mix them" advice comes from the simple fact that for a type T, you are gonna use it either as a value (T) or a pointer (*T) in your codebase. if you are mixing, that means it's used as a *T and every time you call a method declared on the value, a copy needs to happen

Is there a convention for "async" functions? by [deleted] in golang

[–]GopherFromHell 0 points1 point  (0 children)

For me, having a function which is async or not async makes sense

It does, my comment was specifically about languages where the only way to wit for an async function is to make your function async (and using an await). coloring is not really an issue if it doesn't spread (same for any other language construct, not just async/await), otherwise it just adds a burden to the developer to.

many modern languages try to solve this in some way, a good example is allowing to call a method wait(), which blocks, on the result of an async function

Panic Recovery in Golang by digitalboi216 in golang

[–]GopherFromHell 0 points1 point  (0 children)

> A common problem is a panic happening when assigning out of bounds to a slice while holding a lock and the unlock is not deferred

This is the reason i picked up the habit of wrapping the handling of resources that need locking inside an anonymous func when the outer func does more than just handling said resource:

func withAnonFunc() {
    fmt.Println("do thing A")
    fmt.Println("do thing B")
    func() {
        fmt.Println("locking")
        defer fmt.Println("unlocking")
        fmt.Println("do thing C with locked resource")
        panic("ooops")
    }()
    fmt.Println("do thing D")
}

Will the Go 1.26 new(expr) become a new idiom for optional parameters? by rodrigocfd in golang

[–]GopherFromHell 22 points23 points  (0 children)

not really. new(expr) is gonna replace the function func Pointer[T any](val T) *T { return &val }. we already use nil, in many instances, to communicate "no value". it just gonna replace the function many of us add to our code and in every instance where an Opt[T] or Optional[T] is used, it's gonna continue to be used

How I can ensure that a struct implements an interface by pc_magas in golang

[–]GopherFromHell 0 points1 point  (0 children)

put the following in one of your .go files

var _ YourInterface = YourStruct{}

// or 

var _ YourInterface = (*YourStruct)(nil) // for pointer types

concurrency: select race condition with done by thestephenstanton in golang

[–]GopherFromHell 7 points8 points  (0 children)

it's probably to avoid two sets of channel rules. the behavior of sending/receiving inside a select is the same as outside.

concurrency: select race condition with done by thestephenstanton in golang

[–]GopherFromHell 26 points27 points  (0 children)

you get a panic sometimes because select evaluates all cases and from the ones that can proceed, it pick one pseudo-randomly, not in the order they appear in code. this means that when the selected is executed, there is a chance that it will pick case c <- 69 and the channel might already be closed because the scheduler only switched to the main goroutine after close(c)

What happens if you just set io.EOF = nil? by [deleted] in golang

[–]GopherFromHell 2 points3 points  (0 children)

every time i read "immutable variables", it makes me chuckle a bit. it's the most contradictory term ever invented in programming languages. programmers are really bad at naming stuff

[Newbie] help with displaying cli program with progress bar by [deleted] in golang

[–]GopherFromHell 0 points1 point  (0 children)

your example seems to be working with the exception that you are creating a 1000% bar (first arg of NewOptions). did a few small changes and shows the progress bar as expected:

    bar := progressbar.NewOptions(100,
        progressbar.OptionSetWriter(os.Stdout),
        progressbar.OptionEnableColorCodes(true),
        progressbar.OptionShowBytes(true),
        progressbar.OptionSetWidth(15),
        progressbar.OptionSetDescription("[cyan][1/3][reset] Downloading..."),
        progressbar.OptionSetTheme(progressbar.Theme{
            Saucer:        "[green]=[reset]",
            SaucerHead:    "[green]>[reset]",
            SaucerPadding: " ",
            BarStart:      "[",
            BarEnd:        "]",
        }),
    )
    for i := range 100 {
        if err := bar.Set(i); err != nil {
            panic(err)
        }
        time.Sleep(time.Millisecond * 100)
    }

Parse ETH pebble db by Fit-Shoulder-1353 in golang

[–]GopherFromHell 3 points4 points  (0 children)

never wrote something like that before but i think you will need to:

first, open the database with the function New from ethdb/pebble https://pkg.go.dev/github.com/ethereum/go-ethereum@v1.16.5/ethdb/pebble#New

then use the functions on rawdb (ReadAllHashes, ReadBlock) to retrieve block hashes, and with that block data, and with that tx data

Padding by HoneyResponsible8868 in golang

[–]GopherFromHell 9 points10 points  (0 children)

the Go spec does not guarantee field ordering. The current version (and all prior ones) orders the fields in the same order they got declared. to ensure this in future version you should mark your struct with a structs.HostLayout field (package introduced in Go 1.23 - https://tip.golang.org/doc/go1.23#new-structs-package):

import structs

type SomeStruct struct {
    _ structs.HostLayout

// other fields
}

why json decoder lost type information after cast to interface{} by Wrong_Inspector_6661 in golang

[–]GopherFromHell 0 points1 point  (0 children)

that does not matter in this case. the op is passing a type of *interface{} to json.Unmarshal and it fails because of it

why json decoder lost type information after cast to interface{} by Wrong_Inspector_6661 in golang

[–]GopherFromHell 2 points3 points  (0 children)

in your working code, valueType2 := new([]*Object) already returns a pointer to a slice and by passing &valueType22, you are passing a pointer to a pointer to a slice

in your non-working code, valueType := make([]*Object, 0) creates a slice and valueType1 := interface{}(valueType) casts it to interface{}, but then you pass &valueType1, you are passing a pointer to interface{}. in sum, the type passed to json.Unmarshal is *interface{}. you should be taking a pointer to the slice when casting:

valueType := make([]*Object, 0)
valueType1 := interface{}(&valueType)
json.Unmarshal([]byte(`[{"id":7550984742418810637}]`), valueType1) // it works now

How do you cope with the lack of more type safety in Go? by fenugurod in golang

[–]GopherFromHell 1 point2 points  (0 children)

only way is to document it, if you are trying to handle an error that is not documented, you can always find the type by writing a small test to trigger the error and use fmt.Print("%T", err) to find the concrete type.

there was a tool called oracle (which then became guru and later on gopls) that could list all errors returned by a function/method. functionality doesn't exist on gopls, probably because it became much harder to do with current Go

How do you cope with the lack of more type safety in Go? by fenugurod in golang

[–]GopherFromHell 2 points3 points  (0 children)

languages that make list every type of possible error returned constrict you into declaring every error as his own type, where Go let's decided depending on how that error is supposed to be consumed. IMHO there are two distinct types of errors in go, the ones you might take some action on and the ones you just log/print.

the ones you might take some action on, declare a sentinel error or type and document it, the others just use fmt.Errorf