转载自: http://zonov.me/golang-for-rubyists-part-2-go-type-system/ 已获原作者授权
原标题: Golang for Rubyists. Part 2. Go type system
Hello, my dear Golang newcomers. I feel so excited when I start writing this post! This is because I learn in the meantime. If when I’m writing about Ruby or JS I’m mostly describing my experience, probably with some additions of new findings I’ve got during the preparation, however in this particular case I’m learning together with you.The other way to write this would be:
var hello string = "Hello"
var world string = "World"
The construct `:=` is a shortened version of the same, as you may see. It automatically realizes that you want to have a variable, not a constant, and also it automatically grasps your variable type.
In all the examples above we defined variables together with its assignment. What you can also do is to split this up. F.e.
package main
import "fmt"
func main() {
var someString string
someString = "hello"
fmt.Println(someString)
}
(If the overall structure looks unfamiliar to you – check out my previous blog post, where I described the most basics of Golang).
2. Now change your code to be:
package main
import "fmt"
func main() {
var someString string
someString = 123
fmt.Println(someString)
}
Can you guess, what will be the result? Yup, an error. Because it’s a statically typed language, you, script-writers! No auto type conversion for us here, piss off!
someString := true
fmt.Println(!someString)
// will return you a false
Unfortunately this kind of structure, which we all like:
someString := "something"
fmt.Println(!someString)
won’t work.
Make your code to look like this:
package main
import "fmt"
func main() {
doubleQuotedString := "Hello, \nWorld!"
backticksQuotedString := `Hello, \nWorld!`
singleQuotedChar := 'H'
fmt.Println(doubleQuotedString)
fmt.Println(backticksQuotedString)
fmt.Println(singleQuotedChar)
}
Here we use three different notations. The first one is double-quoted, it interprets the special characters, like \n which I use here, so it will split the string into two lines in your output. The second notation uses backticks and kind of safe, so it doesn’t interpret anything inside itself. The third one you’ve already seen in the previous post, it stores a character and returns you its UTF code.
var x float32 = 1.1
var y float32 = 0.2
fmt.Println(x - y)
Lists
Lists are a big topic to discuss, so in this post I will cover it’s types and the basic difference, and let’s start with the most (as you would expect) familiar one.An array is a fixed size ordered homogeneous list. This sentence says for itself. The first thing to know is that once you set up an array size, you cannot change it. The second thing is that if you say that your array consists of numbers, you could not put there any strings. More of that, if you say that your array consists of int32, you cannot put e.g. int64 into it. Already scared? Let’s see some examples.
package main
import "fmt"
func main() {
var x [10]int
fmt.Println(x)
}
This is a syntax to define an array, which will have a length 10 and you expect it to contain integers.
If you run this program, it will print [0 0 0 0 0 0 0 0 0 0]. Now let’s scoff at it and try to feed if with something wrong:
package main
import "fmt"
func main() {
var x [10]int
var number int64 = 42
x[3] = number
fmt.Println(x)
}
Here we first define the array of ints, then define a variable with a type of int64, and then try to feed this variable to the array. And the result as expected is ./main.go:8:8: cannot use number (type int64) as type int in assignment. This just affirms what I wrote above, however one more interesting thing here. As you could notice, we don’t use number-suffixed int type, but just int. And as a Rubyist you could probably expect it to be some generic type, which will accept all the int types, but it is not. Is it just a reference to the int32? Hmm, again missed. It is smth strange, an integer, which may have at least 32 bits of size.
The other way to assign an array is also together with its value:
x := [3]int{5, 6, 7}
Slices
They are actually much more common in the Golang world due to their flexibility. They are still homogeneous, but instead of being fixed in size, they are changeable. Here is a simple snippet:
package main
import "fmt"
func main() {
nums := []int{2, 3, 11, 13}
nums = append(nums, 0, 1)
var s []int = nums[3:len(nums)]
fmt.Println(s)
}
Here we first define a Slice, which definition looks very similar to Arrays, just without a length setting. Then we modify it by adding two elements to the end. Ans as a next step we take elements starting from the index [3] to the end. So your result here will be [13 0 1]. Pretty flexible, huh? However there are some downsides of this structure, we will talk about in some future post.
package main
import "fmt"
func main() {
population := make(map[string]int)
population["Berlin"] = 3500000
population["Munich"] = 1500000
fmt.Println(population)
}
The result will be map[Berlin:3500000 Munich:1500000]. The static typic here cannot stop you from using a deep maps, where elements are containing other maps, like map[string]map[int]. Is your brain already melting? No worries, we’re close to an end. One more new thing here you could notice is a make function. If you define a list with this function, it not just defines it, but also allocates a memory for your structure.