I want to get the memory location address of the map in Go but it returns a concatenated ampersand and the map output.
Here is the example code:
package main
import "fmt"
var name = map[string]string{
"name": "John",
"lastname": "Doe",
}
func main() {
fmt.Println(&name)
}
what it prints is:
&map[lastname:Doe name:John]
I know that maps are copied by references and there is no need to get the address, but how could I retrieve the address?
Println will use the default format based on type, and you already saw what that default format is. You can use Printf to print the pointer:
func main() {
fmt.Printf("%p\n", &name)
}
Well, in Go you can get a memory location pointer of a string variable using the built-in & operator because strings in Go are represented as a pointer to a contiguous block of memory that contains the string's characters. Therefore, you can use the & operator to get a pointer to this memory location.
On the other hand, maps in Go are more complex data structures than strings, and they are represented by a pointer to a runtime structure that contains the map's metadata and the pointer to the underlying data. The exact structure of this runtime map object is subject to change in different versions of the Go runtime. Therefore, the pointer to a map object is not guaranteed to be compatible with other types and may not be used safely without casting or using the unsafe package.
There are two ways to reach the address:
First solution as Burak mentioned is using a format specifier which is helpful if printing the pointer is intended. And the second one is to using unsafe package:
package main
import (
"fmt"
"unsafe"
)
var name = map[string]string{
"name": "John",
"lastname": "Doe",
}
func main() {
ptr := unsafe.Pointer(&name)
fmt.Println(ptr)
}
The unsafe package provides low-level facilities to access and manipulate memory directly, which allows you to work around the type system and access memory locations that are not normally accessible. However, this comes at the cost of safety and portability, so it should be used with care and only when absolutely necessary.
Related
Here's an implementation of a type which stores a syslog Facility value:
package main
import (
"fmt"
)
// Facility - as defined in RFC 5424
type Facility uint8
var facilityName []string = []string{
"kernel",
"user",
"...",
"local7",
}
func (s Facility) String() string {
if int(s) < len(facilityName) {
return facilityName[s]
} else {
return fmt.Sprintf("facility(%d)!", int(s))
}
}
func UnknownFacility() Facility {
return Facility(1) // "user"
}
The problem with this is that it puts it puts facilityName in the package namespace. The alternative is to create this array or slice inside the String() function, but this creates a new slice/array on every call to String(). The generated code isn't efficient.
Is there a way of doing this efficiently and not polluting the namespace?
UnknownFacility() also feels like Hungarian Notation...
The short answer seems to be No.
The Go compiler (1.18.2) doesn't optimize creating a "constant" array / slice in a function, and there's no equivalent in Go of a C/C++ static variable. Such arrays therefore need to be stored in a package variable to avoid the overhead of recreating them on every function call. (See https://godbolt.org/z/TGPE75Kdf for example compiler output).
There's no mechanism to limit the visibility of a variable to a limited number of functions inside a package. (Go lacks an equivalent to a C++ anonymous namespace)
I'm working around this with a naming convention of prefixing variable names which only need file scope with _filename so they can't collide and are easy to distinguish in IDE auto-completion.
Whether adding variable names which only need file or function scope to the internal package namespace is a significant concern is a different question.
I'm interfacing with C code in Go using cgo, and I need to call a C function with a pointer to the underlying value in an Interface{} object. The value will be any of the atomic primitive types (not including complex64/complex128), or string.
I was hoping I'd be able to do something like this to get the address of ptr as an unsafe.Pointer:
unsafe.Pointer(reflect.ValueOf(ptr).UnsafeAddr())
But this results in a panic due to the value being unaddressable.
A similar question to this is Take address of value inside an interface, but this question is different, as in this case it is known that the value will always be one of the types specified above (which will be at most 64 bits), and I only need to give this value to a C function. Note that there are multiple C functions, and the one that will be called varies based off of a different unrelated parameter.
I also tried to solve this using a type switch statement, however I found myself unable to get the address of the values even after the type assertion was done. I was able to assign the values to temporary copies, then get the address of those copies, but I'd rather avoid making these copies if possible.
interface{} has own struct:
type eface struct {
typ *rtype
val unsafe.Pointer
}
You have no access to rtype directly or by linking, on the other hand, even though you'll copy whole rtype, it may be changed (deprecated) at future.
But thing is that you can replace pointer types with unsafe.Pointer (it may be anything else with same size, but pointer is much idiomatic, because each type has own pointer):
type eface struct {
typ, val unsafe.Pointer
}
So, now we can get value contained in eface:
func some_func(arg interface{}) {
passed_value := (*eface)(unsafe.Pointer(&arg)).val
*(*byte)(passed_value) = 'b'
}
some_var := byte('a')
fmt.Println(string(some_var)) // 'a'
some_func(some_var)
fmt.Println(string(some_var)) // 'a', it didn't changed, just because it was copied
some_func(&some_var)
fmt.Println(string(some_var)) // 'b'
You also might see some more usages at my repo:
https://github.com/LaevusDexter/fast-cast
Sorry for my poor English.
I try to check when Golang return a local value as nil, then I use this code.
package main
import (
"fmt"
)
type S struct{}
func InitEfacePointer() interface{} {
var s *S
println(s)
return s
}
func main() {
s := InitEfacePointer()
fmt.Println(s)
//println(s)
}
The output is
0x0
But when I just use println to output value.
package main
type S struct{}
func InitEfacePointer() interface{} {
var s *S
println(s)
return s
}
func main() {
s := InitEfacePointer()
println(s)
}
The output changed to
0x0
(0x93d40,0x0)
Could anyone explain the mechanism of this behavior? Thanks!
You shouldn't be using the builtin println, it clearly states:
The println built-in function formats its arguments in an
implementation-specific way and writes the result to standard error.
Spaces are always added between arguments and a newline is appended.
Println is useful for bootstrapping and debugging; it is not
guaranteed to stay in the language.
And the spec also mentions:
Current implementations provide several built-in functions useful
during bootstrapping. These functions are documented for completeness
but are not guaranteed to stay in the language. They do not return a
result.
Implementation restriction: print and println need not
accept arbitrary argument types, but printing of boolean, numeric, and
string types must be supported.
This is it. print and println are useful debugging tools but should not be relied upon to:
provide a specific output
provide the same output on different platforms
provide the same output over time
exist
That said, I'm guessing that in your case it is printing the internal interface fields: a pointer to a type, and a value.
First of all, fmt.Println and builtin println are very different matteres: they are different both in implentation and in purpose. fmt.Println deals with many complex cases using reflect while println only deal with some base cases and is only for "bootstrap or debug" (as the spec says).
In this specific case, you are printing an interface{} you returned from InitEfacePointer(). The fmt.Println looks into the interface using reflect and gets the underlying data: a nil pointer to a string and it then prints it out: 0x0. On the other hand, builtin println takes the interface and by magic of the compiler (or not), it recognize it is an interface. As this post, golang interface are auctually two pointers, one to information about the type stored and one to the underlying data. So the builtin printlngoes into the interface details, 0x93d40 being the "type info" and 0x0 being the underlying data. (The first 0x0 is from the function call).
Furthermore, testing whether the returned interface is nil seems like a common mistake. Read here: https://golang.org/doc/faq#nil_error
What's the difference? Is map[T]bool optimized to map[T]struct{}? Which is the best practice in Go?
Perhaps the best reason to use map[T]struct{} is that you don't have to answer the question "what does it mean if the value is false"?
From "The Go Programming Language":
The struct type with no fields is called the empty struct, written
struct{}. It has size zero and carries no information but may be
useful nonetheless. Some Go programmers use it instead of bool as the
value type of a map that represents a set, to emphasize that only the
keys are significant, but the space saving is marginal and the syntax
more cumbersome, so we generally avoid it.
If you use bool testing for presence in the "set" is slightly nicer since you can just say:
if mySet["something"] {
/* .. */
}
Difference is in memory requirements. Under the bonnet empty struct is not a pointer but a special value to save memory.
An empty struct is a struct type like any other. All the properties you are used to with normal structs apply equally to the empty struct. You can declare an array of structs{}s, but they of course consume no storage.
var x [100]struct{}
fmt.Println(unsafe.Sizeof(x)) // prints 0
If empty structs hold no data, it is not possible to determine if two struct{} values are different.
Considering the above statements it means that we may use them as method receivers.
type S struct{}
func (s *S) addr() { fmt.Printf("%p\n", s) }
func main() {
var a, b S
a.addr() // 0x1beeb0
b.addr() // 0x1beeb0
}
I'm quite new to Go, so this might be obvious. The compiler does not allow the following code:
(http://play.golang.org/p/3sTLguUG3l)
package main
import "fmt"
type Card string
type Hand []Card
func NewHand(cards []Card) Hand {
hand := Hand(cards)
return hand
}
func main() {
value := []string{"a", "b", "c"}
firstHand := NewHand(value)
fmt.Println(firstHand)
}
The error is:
/tmp/sandbox089372356/main.go:15: cannot use value (type []string) as type []Card in argument to NewHand
From the specs, it looks like []string is not the same underlying type as []Card, so the type conversion cannot occur.
Is it, indeed, the case, or did I miss something?
If it is the case, why is it so? Assuming, in a non-pet-example program, I have as input a slice of string, is there any way to "cast" it into a slice of Card, or do I have to create a new structure and copy the data into it? (Which I'd like to avoid since the functions I'll need to call will modify the slice content).
There is no technical reason why conversion between slices whose elements have identical underlying types (such as []string and []Card) is forbidden. It was a specification decision to help avoid accidental conversions between unrelated types that by chance have the same structure.
The safe solution is to copy the slice. However, it is possible to convert directly (without copying) using the unsafe package:
value := []string{"a", "b", "c"}
// convert &value (type *[]string) to *[]Card via unsafe.Pointer, then deref
cards := *(*[]Card)(unsafe.Pointer(&value))
firstHand := NewHand(cards)
https://play.golang.org/p/tto57DERjYa
Obligatory warning from the package documentation:
unsafe.Pointer allows a program to defeat the type system and read and write arbitrary memory. It should be used with extreme care.
There was a discussion on the mailing list about conversions and underlying types in 2011, and a proposal to allow conversion between recursively equivalent types in 2016 which was declined "until there is a more compelling reason".
The underlying type of Card might be the same as the underlying type of string (which is itself: string), but the underlying type of []Card is not the same as the underlying type of []string (and therefore the same applies to Hand).
You cannot convert a slice of T1 to a slice of T2, it's not a matter of what underlying types they have, if T1 is not identical to T2, you just can't. Why? Because slices of different element types may have different memory layout (different size in memory). For example the elements of type []byte occupy 1 byte each. The elements of []int32 occupy 4 bytes each. Obviously you can't just convert one to the other even if all values are in the range 0..255.
But back to the roots: if you need a slice of Cards, why do you create a slice of strings in the first place? You created the type Card because it is not a string (or at least not just a string). If so and you require []Card, then create []Card in the first place and all your problems go away:
value := []Card{"a", "b", "c"}
firstHand := NewHand(value)
fmt.Println(firstHand)
Note that you are still able to initialize the slice of Card with untyped constant string literals because it can be used to initialize any type whose underlying type is string. If you want to involve typed string constants or non-constant expressions of type string, you need explicit conversion, like in the example below:
s := "ddd"
value := []Card{"a", "b", "c", Card(s)}
If you have a []string, you need to manually build a []Card from it. There is no "easier" way. You can create a helper toCards() function so you can use it everywhere you need it.
func toCards(s []string) []Card {
c := make([]Card, len(s))
for i, v := range s {
c[i] = Card(v)
}
return c
}
Some links for background and reasoning:
Go Language Specification: Conversions
why []string can not be converted to []interface{} in golang
Cannot convert []string to []interface {}
What about memory layout means that []T cannot be converted to []interface in Go?
From the specs, it looks like []string is not the same underlying type as []Card, so the type conversion cannot occur.
Exactly right. You have to convert it by looping and copying over each element, converting the type from string to Card on the way.
If it is the case, why is it so? Assuming, in a non-pet-example program, I have as input a slice of string, is there any way to "cast" it into a slice of Card, or do I have to create a new structure and copy the data into it? (Which I'd like to avoid since the functions I'll need to call will modify the slice content).
Because conversions are always explicit and the designers felt that when a conversion implicitly involves a copy it should be made explicit as well.