Why assign a reference to a struct in go? - reference

I'm having a look at the code at this page:
http://golang.org/pkg/net/http/
And there's one thing I don't understand - at some point, a new structure is created and initialized like this:
client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
Why use & when creating this structure?
I've also read this blog post and structs are initialized like this:
r := Rectangle{}
What is the difference between both and how should I know which one to use?

The difference is in the type of your variable.
client := &http.Client{
makes client of type *http.Client
while
client := http.Client{
builds a http.Client.

The top one is returning a pointer. It is a Go idiom instead of using new. The second one is just a value object. If you need a pointer use the top.
Check the effective go doc for more about this
http://golang.org/doc/effective_go.html#allocation_new

In object-oriented programming, in order for an object to have dynamic lifetime (i.e. not tied to the current function call), it needs to be dynamically allocated in a place other than the current stack frame, thus you manipulate the object through a pointer. This is such a common pattern that in many object-oriented languages, including Java, Python, Ruby, Objective-C, Smalltalk, JavaScript, and others, you can only deal with pointers to objects, never with an "object as a value" itself. (Some languages though, like C++, do allow you to have "objects as values"; it comes with the RAII idiom which adds some complexity.)
Go is not an object-oriented language, but its ability to define custom types and define methods that operates on that custom type, can be made to work very much like classes and methods. Returning a pointer to the type from the "constructor" function allows the "object" to have a dynamic lifetime.

When we use reference, we use a single item throughout the program runtime. Even if we assign that to a new variable or pass through a function. But when we use value, we make new copies of individual items.
( Reference is not right word according to golang convention. "Address of value" would be more appropriate here https://golang.org/ref/spec#Package_initialization )
An example will make it much clear I hope.
type Employee struct {
ID int
Name string
Address string
}
func main() {
andy := &Employee{}
andy.Name = "Andy"
brad := andy
brad.Name = "Brad"
fmt.Println(andy.Name)
}
The result of this code block would be:
Brad
As we made new variable from it but still referring to same data. But if we use value instead of reference and keep the rest of the code same.
// from
andy := &Employee{}
// to
andy := Employee{}
This time the result would be:
Andy
As this time they both are individual items and not referring to same data anymore.

Related

Why can't I use C#9's "with" keyword to create a copy of structs (like with records)

C# 9 has a new feature. A record type. The record is just a class, but with a bunch of automatically created functions and properties. But basically the idea (as I undstand it) was, a class that behaves like structs, for things like copying, coimparison with Equals, immutibility and so on.
Also with the record type was a new feature with the keyword "with". To create a copy of a record, you can write something like that: var copy = original with { Property = new_value, };
Now I wondered, if records were designt to behave like structs (but are classes). Why doesn't the new "with" keyword works also with structs. I mean, as far as I can tell, structs have all features, that are necessary for this feature. Like they are copied by value.
Instead to use similar features for structs, I have to write a copy constructor and can then write: var copy = new StructType(original) { Property = new_value, };
Short answer:
That's how the feature was designed.
Long answer:
The compiler creates a synthesized clone method with a reserved name <Clone>$, when you use with keyword, the compiler calls this clone method, and then modifies whatever properties you want to modify.
structs or classes doesn't have a synthesized clone method. Hence, with can't be used with them.
You may want to write a language proposal to extend the usage of with keyword.
Edit:
Currently, there is a proposal for allowing record structs. See Proposal: record structs for more information. This is what you may want.

Delphi 7 with..do statement doesen't work with variant variable

I'm working with Microsoft Excel via Delphi 7. It works fine but while formatting rows and ranges I have to write such long strings.
XLApp.Workbooks[1].WorkSheets[NameDoc].Range['A19:L19'].Font.Bold := true;
So I want to get rid of hard work and do it via "with..do" statement like this
with XLApp.Workbooks[1].WorkSheets[NameDoc] do
begin
Range['A19:L19'].Font.Bold := true;
end;
But at compilation stage I see this error
Record, object or class type required
on string - "with..do".
I creating Excel object this way
XLApp: Variant;
XLApp := CreateOleObject('Excel.Application');
I consider that with..do statement doesen't works with variant type variable, but I want to know whether I'm right or not? And if I'm right is there any workaround to make it work?
Variant can be anything or nothing at all - compiler doesn't know it and cannot know: it is so called "dynamically typed value". Since it does not know - it does not know if there would be any members (properties, methods) and if there would - what names would they have.
To get the benefits of strong compile-time typing - including using of with but not only - you have to use interface variables, those that are provided by TExcelApplication component and underlying unit having those values "statically typerd" - thus providing for Delphi compiler to know value types when compiling, in before running. There are plenty of types like iWorsksheet, iRange and others in that unit.
Borland Delphi 7 TExcelApplication.Connect works on office machines but not at client
http://www.delphipages.com/forum/showthread.php?t=157889
http://delphikingdom.ru/asp/viewitem.asp?catalogid=1270
However, since that is about reference-counting and lifetime I'd suggest you go with explicit use of temp variables rather than using with with and implicit invisible variables. Since you cannot control their lifespan and their clearance you might hit the wall in some unexpected place later. I did.
var tmpR: iRange; // assuming we have statically-typed API
// for example - providing we using ExcelXP or Excel2000 unit
tmpR := XLApp.Workbooks[1].WorkSheets[NameDoc];
tmpR.Range['A19:L19'].Font.Bold := true; // instead of with
with tmpR do // also possible but gives little benefit now
begin // when we made a dedicated temp var
Range['A19:L19'].Font.Bold := true;
end;
tmpR := nil; // crucial unless the most short and simplistic functions
// just release hold on Excel's object - let it manage its memory freely,
// by letting Excel know your program no more uses that object.
Also read
https://en.wikipedia.org/wiki/Automatic_Reference_Counting
https://en.wikipedia.org/wiki/Component_Object_Model
Can with be used with a Variant?
No.
You can use with for types whose members are known at compile time. But variants, for which the . operator is evaluated at run time, do not fall into this category. Hence with is not available for variants.
The documentation says, with my emphasis:
A with statement is a shorthand for referencing the fields of a record
or the fields, properties, and methods of an object. The syntax of a
with statement is:
with obj do statement
or:
with obj1, ..., objn do statement
where obj is an expression yielding a reference to a record, object
instance, class instance, interface or class type (metaclass)
instance, and statement is any simple or structured statement.

Naming Vars with strings

Can a variable be named with a string or character array, in any language? Basically I want something like:
Var_String = "varname"
Var_String as double
And then I could fill the double varname.
If it helps im trying to make a program that can declare variables on the fly, while running. Even if thats not possible, I am open to workarounds even if they're impractical, although I would prefer that workarounds be in VB6, C++, or PHP, because I know those languages already, but they dont have to be.
Javascript is completely capable of declaring variable names on the fly. A javascript object can be treated "associatively" as a dictionary. Observe:
var testyObject = function()
{
Awesome = "hello";
};
var myObject = new testyObject();
alert(myObject.Awesome); // creates an alert window that says hello
alert(myObject['Awesome']); // the same as above
myObject[myObject.Awesome] = "woo!"; // We just created a property on the object with the name "hello"
alert(myObject.hello); // creates an alert window that says "woo!"
I also believe you can add them to your immediate scope rather than as properties on other objects by using this["whatever you want it named"] = "woo!"; but I'm not certain, someone can correct me on that if such does not work.
You can read more about associative arrays at http://www.quirksmode.org/js/associative.html
The usual way to do something like this is called a hash. You store name/value pairs and given the name, can look up its value. You can generally define them to store any sort of object. In fact, in some languages, objects themselves are essentially hashes with a few extra properties.
You can find more information on wikipedia: http://en.wikipedia.org/wiki/Hash_table

Is it possible to take the name of a variable and turn it into a string in ActionScript 3.0?

I am making a simple debugger window in ActionScript for myself where I can add and remove variables I want to track. I was to be able to add variables to the list by just doing something like
DebuggerMonitor.trackVar(variable).
My question is, is there any way I can turn "variable" itself (the name, not the value) into a String to be added into a text field?
Depending on how "intelligent" your debugger should be, you could just pass the name along:
DebuggerMonitor.trackVar( variable, "variable" );
since obviously, when used in a context like this, the name should be known at the time you are writing the program.
You can also do some reflection magic to get instance variable names, but it won't work for temp variables (their names are dropped at compilation time):
public function getVariableName( instance:*, match:* ):String {
var typeDescription:XML = describeType( instance );
var variables:XMLList = typeDescription..variable;
var accessors:XMLList = typeDescription..accessor;
for each(var variable:XML in variables)
if(matchesXMLName( instance, variable, match ))
return variable.#name;
for each(var accessor:XML in accessors)
if(matchesXMLName( instance, accessor, match ))
return accessor.#name;
return "No name found.";
}
private function matchesXMLName( instance:*, xml:XML, match:* ):Boolean {
return match == instance[xml.#name.toString()];
}
var varName:String = getVariableName ( myObject, variable );
Using reflections like this will also be quite costly, if used often - you will have to think of a way to cache the type descriptions.
I recommend you check out the as3commons reflections package - there is a lot of useful functionality in there...
Short answer - No :(
You can access the type name but not individual instance names, as these are lost at run-time.
There is a confusion caused by the keyword 'var' because it is used to create several types of bindings.
Lexical bindings (the keyword 'var' was used inside a function).
Dynamic bindings (the keyword 'var' was used to declare a class' field).
Lexical bindings are interpreted by the compiler at compile time as addresses of the registers of the registers space occupied by the function. The names given to lexical bindings perish at this time and it is not possible to restore them at runtime - therefore you can't get the "name" of the variable.
Dynamic bindings are a kind of "public API" of the objects that declare them, they may be accessed from the code that was not compiled together with the code that created them, this is why, for the purpose of reflection the names of these bindings are stored in compiled code. However, ActionScript has no way of referencing LHS values, so you cannot, even if you know the name of the variable and the object declaring it, pass it to another function. But you can look it up in the debugger or by calling describeType on the object declaring the variable. Note that describeType will not show information on private variables even if you are calling it from the scope of the object in question.

dynamic as a return type

I'm in a situation where I need to return an object of an anonymous type from a method, is it a good idea to use dynamic as a return type? what considerations to take?
public dynamic MyMethod()
{
// process and return the object of an anonymous type
}
It doesn't make any sence, you can return object with the same effect.
P.S.: Also anonymous types are not that good as return types.
Yes it has sense If you "guarantee" that you'll always return an object with some characteristics , with an Id for example (ignoring that perhaps it would be better to use an Interface)
public dynamic MyMethod()
{
var temp = new ExpandoObject();
temp.Id = 5;
return temp;
}
Console.WriteLine(MyMethod().Id);
So if you guarantee that all your objects can Turn Left-Right but you don't guarantee if they are airplanes, cars, motos, boats. (so it's good if you are doing Duck typing When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.)
Note that if you then need to reflect on your objects, it can become ugly: How do I reflect over the members of dynamic object?
Returning a dynamic object does have the benifit of allowing you to access the properties from the anonmymous type without using reflection (albeit without intellisense). If you take this approach you need to make sure that the properties on the anonymous type match what you are accessing on the dynamic object. Otherwise you will get runtime errors
However, I would suggest you consider returning a concrete type instead

Resources