&http.Client in Golang, Need Explanation - go

I found the following code
client := &http.Client
What does & mean? What kind of value that client var receives

& is the "pointer to" operator, similar to c. The client variable holds a pointer to the value of http.Client.

client here is a pointer to the instance of http.Client.
It is same as:
var client *http.Client
client = &http.Client{...}

Related

Missing Field or Method [duplicate]

This question already has an answer here:
Why there are two ways of declaring variables in Go, what's the difference and which to use?
(1 answer)
Closed 7 months ago.
var client := http.Client
For whatever reason this code is giving the error message missing variable or initialization. Can someone enlighten me on why? I'm not understanding what I have done wrong.
In Go we use := or var = for initializing variables. In your case you can re-write it to be:
var client = http.Client{}
or
client := http.Client{}
Either of these will trigger type inference of the variable. You can use var with a type to explicitly declare a type as well. In your case if you wanted to enforce the type you could write:
var client http.Client = http.Client{}

Declare a variable without datatype

I have a piece of code that needs a variable declaration w/o its type. The variable is assigned a value later and that is an interface. pseudo code will look very similar to this:
var client
if some_condn {
client = ssh.Dial(params)
} else {
client = my_own_ssh_dial(my_params)
}
session,_ := client.NewSession()
The problem is GO does not allow a variable declaration w/o type. Is there any way I can use something like an generic Object (from Java) to default client to start with?
TIA
A variable must have a type in order to use it. The closest thing to an untyped variable would be the type interface{}, which is an interface type, but has no methods to call.
Since the goal here is to call the NewSession method, declare the variable with an interface containing that method.
var client interface {
NewSession() (*ssh.Session, error)
}
if some_condn {
client = ssh.Dial(params)
} else {
client = my_own_ssh_dial(my_params)
}
session, _ := client.NewSession()
I'm pretty new to Go, but I'll take a stab. If it's wrong, cool. Unfortunately, I don't have enough code from you to actually try and do this - but essentially, you'll need to make your own type my_own_ssh, and then add a Dial function to it. Then, you'll define an
interface Client {
Dial()
}
And then you can define your client variable with var client Client before the conditional check. You'll also need to create a function Dial that has a my_own_ssh receiver in order for the interface to work/make sense.
I'm very happy to receive feedback on this answer, because like I said - I'm pretty new to it :)

How do you use Thrift's TMemoryBuffer in Golang?

In Go, I have a byte array data []byte which I am trying to read into an object generated by Thrift. In C# the working code is as follows:
var request = new Request();
using (var transport = new TMemoryBuffer(data))
using (var protocol = new TBinaryProtocol(transport))
{
request.Read(protocol);
}
However in Go, it does not work:
request := app.NewRequest()
transport := thrift.TMemoryBuffer{
Buffer: bytes.NewBuffer(data),
}
protocol := thrift.NewTBinaryProtocolTransport(transport) // error here
request.Read(protocol)
The error it gives is:
cannot use memoryBuffer (type thrift.TMemoryBuffer) as type thrift.TTransport in argument to thrift.NewTBinaryProtocolTransport:
thrift.TMemoryBuffer does not implement thrift.TTransport (Close method has pointer receiver)
I am unsure of how to fix this, as TMemoryBuffer does not seem to implement TTransport and I can't find documentation of how TMemoryBuffer should be used instead.
The important part of that error is Close method has pointer receiver.
A function can be defined on a type, or a pointer to that type (i.e a pointer receiver), the TTransport interface defines a function Close with a pointer receiver.
Read the tour of go for a refresher on pointer receivers.
Changing your code to the following, should work:
transport := &thrift.TMemoryBuffer{
Buffer: bytes.NewBuffer(data),
}
One way to think about the problem would be that thrift.TMemoryBuffer does not have Close function defined on it, but that *thrift.TMemoryBuffer does. And the function NewTBinaryProtocolTransport requires a type with a Close function defined as specified by the interface.

Need to construct interface/pointer using Reflect in Golang, not working

So, this works:
house := model.House {};
err = db.First(&house).Error;
However, this doesn't work:
var house model.House;
fetchFromDatabase := reflect.New(reflect.TypeOf(house)).Interface();
err = db.First(&fetchFromDatabase).Error;
... The database library gives the error:
unsupported destination, should be slice or struct
To me, that should be a struct, considering the "House" type is a struct. However, I'm still wrapping my head around Reflect ... can anyone help?
The library is complaining because the application is passing a *interface{} to the method. The value fetchFromDatabase is a pointer to a struct. Pass this value directly to the method:
var house model.House
fetchFromDatabase := reflect.New(reflect.TypeOf(house)).Interface()
err = db.First(fetchFromDatabase).Error

Why does go require you to add & before a variable name?

Here is a snippet that I am looking at:
var t txn
t.c = c
err := c.read(&t.req)
Why do you have to write &t and not just t.req?
You don't always have to use the ampersand. In your example it depends on the signature of c.read, which asks for a pointer (* before the type, such as *MyStruct). & returns the address of a value, giving you a pointer to it, so &t.req satisfies read's signature.
For further reading, see the FAQ on pointers and the spec on Address operators.

Resources