Golang : convert Byte slice array to integer array - http

In Golang, the code [body, err := ioutil.ReadAll(resp.Body)], the ioutil.ReadAll() returns a byte Slice array, based on the documentation.
This is stored in the variable 'body'. My question is how to convert this byte Slice array, to an array of Integers.

I just found some code that does what I was wanting:
import "fmt"
import "strconv"
func main() {
var t = []string{"1", "2", "3"}
var t2 = []int{}
for _, i := range t {
j, err := strconv.Atoi(i)
if err != nil {
panic(err)
}
t2 = append(t2, j)
}
fmt.Println(t2)
}
So this code, does do what I want.
BUT l am disappointed in Golang, for not having a nice one liner that could do this
kind of conversion.
Certain basic things like this, should be packaged up for the programmer, and not have to do this kind of 'low' level programming.
Note, i still like Golang, they had done a lot to make a better C type language that has higher level Data Types when compared to C and also make some things more dynamic compared to C.
SO just disappointed they did not make a High Abstraction for this kind of case, which comes up quite a bit.

Related

How do cleanly initialize two structs in golang which depend on each other?

I've run into an issue in my current project where I have two modules, one implementing an interface for testing purposes, and one just a concrete struct, which each depend on a method from the other.
In order to resolve this tension, I've attempted to create a top-level "container" struct that holds a reference to the dependent struct and interface, and then with a method on the container struct, assign as a member of each component struct that top level container's pointer to the other struct. I am doing this instead of using globals in order to be able to better encapsulate my code for testing purposes.
However, it seems that whichever struct is initialized first does not see the change in the other struct's address when the second struct is initialized. I do not understand why, and I don't seem to be able to make this function as expected.
Since there are many extraneous details in the actual code I've created this toy example to illustrate what I'm talking about.
type container struct {
r requestor
a *A
}
type requestor interface {
Request()
}
type A struct {
r requestor
}
type R struct {
a *A
}
func (r R) Request() {
log.Info("I requested")
return
}
func (container *container) NewA() *A {
log.Info("New A received container.r: ", container.r)
a := &A{
r: container.r,
}
container.a = a
return a
}
func (container *container) NewR() *R {
r := &R{
a: container.a,
}
container.r = r
return r
}
func TestDepResolution(t *testing.T) {
top := container{}
top.NewR()
top.NewA()
// top.a.r = r
log.Infof("top: %+v", top)
log.Infof("R: %+v", top.r)
log.Infof("A: %+v", top.a)
}
It's setup as a test so I can easily execute it within my project. The output is as such:
=== RUN TestDepResolution
INFO[0000] New A received container.r: <nil>
INFO[0000] top: {r:0xc000010028 a:0xc00006abc0}
INFO[0000] R: &{a:0xc00006abc0}
INFO[0000] A: &{r:<nil>}
I expected that A's r variable would become equal to top's r variable after NewR() was called, but it doesn't seem to change. The same issue occurs the other way around if I switch the order of NewA() and NewR().
I expected since I am using pointers and interfaces here that the values would be connected when top's values changed, but it's apparent I must be misunderstanding something. I've tried playing around with the pointers quite a bit to no avail.
So why doesn't this work as I expected? Is there a way to make this work as I've proposed? Or am I thinking about this issue in an entirely wrongheaded way? I have tried to think about extracting functionality from the modules so that they are not mutually dependent and I could avoid this issue entirely, but I have not been able to come up with a good way to do so.
To be able to utilize pointers the way you seem to want to, you first need actual pointers (i.e. not nil pointers) and you also need to use pointer indirection to be able to "share" the updates to the pointed values.
For example:
type T struct { F string }
a := &T{"foo"} // non-nil pointer
b := a
fmt.Println(b) // output: {"foo"}
*a = T{"bar"} // pointer indirection
fmt.Println(b) // output: {"bar"}
For comparison, here's what your code is attempting to do:
type T struct { F string }
a := (*T)(nil) // nil pointer
b := a
fmt.Println(b) // output: <nil>
a = &T{"bar"} // plain assignment
fmt.Println(b) // output: <nil>
And note that even if you used pointer indirection, it is illegal to do so on a nil pointer and the runtime, if it encounters such an operation, will panic.
a := (*T)(nil) // nil pointer
b := a
fmt.Println(b) // output: <nil>
*a = T{"bar"} // pointer indirection on nil, will crash the program
fmt.Println(b)
So, your example doesn't work because it does not properly initialize the pointers and it does not use pointer indirection, rather, it uses simple assignment which just updates the target variable's pointer and not the pointed-to value.
To initialize the container properly you should do it in one step:
func NewContainer() *container {
c := &container{a: &A{}}
c.r = &R{a: c.a}
c.a.r = c.r
return c
}
https://play.golang.com/p/hfbqJEVyAHZ
Or, if you want to do it in two, you can do something like this:
func (c *container) NewA() *A {
log.Println("New A received c.r: ", c.r)
a := &A{
r: c.r,
}
if c.a != nil {
*c.a = *a
} else {
c.a = a
}
return a
}
func (c *container) NewR() *R {
if c.a == nil {
c.a = new(A)
}
r := &R{
a: c.a,
}
c.r = r
c.a.r = r
return r
}
https://play.golang.com/p/krmUQOsACdU
but, as you can see, the multi step approach to initializing so tightly coupled dependencies can get unnecessarily convoluted and ugly, i.e. complex, i.e. very much error prone. Avoid it if you can.
All that said, personally, I would consider this kind of circular dependency a smell and would start thinking about redesign, but maybe that's just me.

convert array of strings from CGO in GO

Can I convert an array of strings (char**) returned from a C (cgo) function in Go?
The code below compiles and runs, but I'm unable to range through a list of strings.
And I'm not even sure if it breaks the rules on "passing pointers": https://golang.org/cmd/cgo/
Any thoughts would be helpful, it's been years since I coded in C! Thanks in advance!
package main
/*
#include "stdlib.h"
char** getlist ()
{
char **array = NULL;
array = (char**)realloc(array, 2*sizeof(*array));
array[0]="HELLO";
array[1]="WORLD";
return array;
}
*/
import "C"
import (
"log"
"unsafe"
)
func main() {
list := C.getlist();
log.Printf("\n========\n C.getList()=%s", list)
ulist := unsafe.Pointer(list)
log.Printf("\n========\nulist=%s", ulist)
}
In order to iterate over the strings in Go, you need to convert the array to a Go slice. We can skip allocation here, and convert it directly (your example statically sets the length to 2, but in practice you would likely have another source for this size)
cSlice := (*[1 << 28]*C.char)(unsafe.Pointer(list))[:2:2]
We can iterate over this directly, and use the C.GoString function to convert the C strings. This is safer to store since it's copying the data to Go memory, but if this slice were exceptionally large we could save the allocation with the same unsafe conversion as above, though you would first need to find the length of each string.
var slice []string
for _, s := range (*[1 << 28]*C.char)(unsafe.Pointer(list))[:2:2] {
slice = append(slice, C.GoString(s))
}
After a couple hours of browsing, I found this concise solution (source):
list := C.getList()
length := 2
slice := make([]string, length)
for _, v := range unsafe.Slice(list, length) {
slice = append(slice, C.GoString(v))
}
For your length guessing issue, you can just make your C function take a pointer to a string array and return the size. It would then look like this:
var list **C.char
length := C.getList(&list)
slice := make([]string, length)
for _, v := range unsafe.Slice(list, length) {
slice = append(slice, C.GoString(v))
}

Accessing a Memory Address From a String in Go?

In golang, can I print the value of a memory address from a given string?
For example, if run the following code:
a := "A String"
fmt.Println(&a)
It prints 0x1040c108.
How could I take a string such as 0x1040c108 and print the value of that string stored in the memory? Something like fmt.Println(*0x1040c108)
Is this possible?
This can be done, but it is a really really REALLY bad idea. Anytime you are importing the unsafe package, you are either doing something wrong, or something really hardcore. I'm hesitant to even answer this, but here goes.
https://play.golang.org/p/unkb-s8IzAo
package main
import (
"fmt"
"strconv"
"unsafe"
)
func main() {
// original example manually examined the printed address and used the value
// updated to preserve forward compatibility due to runtime changes shifting the address over time
hi := "HI"
// getting address as string dynamically to preserve compatibility
address := fmt.Sprint(&hi)
fmt.Printf("Address of var hi: %s\n", address)
// convert to uintptr
var adr uint64
adr, err := strconv.ParseUint(address, 0, 64)
if err != nil {
panic(err)
}
var ptr uintptr = uintptr(adr)
fmt.Printf("String at address: %s\n", address)
fmt.Printf("Value: %s\n", ptrToString(ptr))
}
func ptrToString(ptr uintptr) string {
p := unsafe.Pointer(ptr)
return *(*string)(p)
}
And yes, this was pretty much taken almost line for line from the unsafe godoc. https://godoc.org/unsafe
Also note that if/when your memory reference is NOT a go string, everything will come crashing down catastrophically. And that go vet is configured to send you an angry message for doing this, reinforcing that this is indeed a bad idea.
UPDATE: Updated example to run on playground as of go 1.15.1, which either the playground or go itself has changed the way the memory is addressed. Or the more likely case that changes in core libs/runtime will shift the address across versions. It now dynamically obtains the address vs a manually hardcoded value.
package main
import "C"
import (
"log"
"strconv"
"unsafe"
)
func main() {
// parse the string into an integer value
addr, _ := strconv.ParseInt("0x1040c108", 0, 64)
// cast the integer to a c string pointer
ptr := (*C.char)(unsafe.Pointer(uintptr(addr)))
// convert to a go string (this will segfault)
str := C.GoString(ptr)
// print it
log.Println(str)
}
Yes!! you can store the address in a pointer variable and print its value by derefrencing it
i := "something"
ptr := &i
fmt.Println(*ptr)
For accessing the memory using a hard coded address such as 0x1040c108, it is necessary for your program to have access to that memory address otherwise, you will get an error saying invalid indirection of a pointer or segmentation fault.

Pointer arithmetic in Go

Considering you can (can't think of a great way to put it, but) manipulate pointers in Go, is it possible to perform pointer arithmetic like you would in C, say for iterating over an array? I know loops are just fine for that kind of things these days but I'm just curious if it's possible.
No. From the Go FAQ:
Why is there no pointer arithmetic?
Safety. Without pointer arithmetic it's possible to create a language that can never derive an illegal address that succeeds incorrectly. Compiler and hardware technology have advanced to the point where a loop using array indices can be as efficient as a loop using pointer arithmetic. Also, the lack of pointer arithmetic can simplify the implementation of the garbage collector.
That being said, you can get around this by using the unsafe package, but just don't:
package main
import "fmt"
import "unsafe"
func main() {
vals := []int{10, 20, 30, 40}
start := unsafe.Pointer(&vals[0])
size := unsafe.Sizeof(int(0))
for i := 0; i < len(vals); i++ {
item := *(*int)(unsafe.Pointer(uintptr(start) + size*uintptr(i)))
fmt.Println(item)
}
}
https://play.golang.org/p/QCHEQqy6Lg
As of Go 1.17, we now have unsafe.Add, which makes it a little easier:
package main
import (
"unsafe"
)
func main() {
vals := []int{10, 20, 30, 40}
ptrStart := unsafe.Pointer(&vals[0])
itemSize := unsafe.Sizeof(vals[0])
for i := 0; i < len(vals); i++ {
item := *(*int)(unsafe.Add(ptrStart, uintptr(i)*itemSize))
println(item)
}
}
Playground.

Behavior of a pointer to an element of `slice` after the `slice` had been appended to

I am wondering what is the behavior of a pointer to an element of slice after the slice had been appended to, for example:
package main
import "fmt"
func main() {
my_slice := []int {3}
silly_ptr := &my_slice[0]
// Do we know that silly_ptr points to value equal 3
// all the time? (If we don't explicitly change it).
fmt.Printf("%p\n", silly_ptr)
fmt.Println(*silly_ptr)
for i := 0; i < 10; i++ {
my_slice = append(my_slice, i)
}
silly_ptr_2 := &my_slice[0]
fmt.Printf("%p\n", silly_ptr_2)
fmt.Println(*silly_ptr_2)
}
Produces: (no surprises)
0xc20800a200
3
0xc20805a000
3
I know that when appending to dynamic array, at certain points we have repopulate the entire array, and therefore memory address of the original array elements is not reliable. To the best of my knowledge similar code is valid in c++, but silly_ptr could be pointing to anything. rust does not allow mutating a vector if it is being borrowed, so the above logic would not compile.
But what about Go? I know that by escape analysis it is valid to return a pointer to a local variable, the variable would be just created on the heap for you. My intuition tells me that the same logic applies in the above case. The memory location where silly_ptr is pointing to will not be repopulated, and hence will always store 3 (if we don't explictly change it). Is this right?
No, it will not always store 3.
Go has memory management. As long as there is an active pointer to an underlying array for a slice, the underlying array is pinned, it will not be garbage collected. If you have a pointer to an element of an underlying array, you can change the value of the element. For example,
package main
import (
"fmt"
)
func pin() *int {
s := []int{3}
fmt.Println(&s[0])
a := &s[0]
s = append(s, 7)
fmt.Println(&s[0])
return a
}
func main() {
a := pin()
fmt.Println(a, *a)
*a = 42
fmt.Println(a, *a)
}
Output:
0xc82000a340
0xc82000a360
0xc82000a340 3
0xc82000a340 42
A slice descriptor contains a pointer to an underlying array so you can see something similar with a slice. For example,
package main
import (
"fmt"
)
func pin() []int {
s := []int{3}
fmt.Println(&s[0])
d := s
s = append(s, 7)
fmt.Println(&s[0])
return d
}
func main() {
d := pin()
fmt.Println(&d[0], d)
d[0] = 42
fmt.Println(&d[0], d)
}
Output:
0xc82000a340
0xc82000a360
0xc82000a340 [3]
0xc82000a340 [42]

Resources