对照 Ruby 学 Go (Part 2): Go 类型

转载自: 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.
And today’s post will be about types and logical structures of Go. Let’s start!

Did you ever work with statically typed languages? I had some experience. F.e. Swift lang I really enjoyed, including their strong type system with optional values, also when I wrote an app using Clojure I didn’t have much pain with their strong dynamic typing. However, on my daily base, I’m usually enjoying (am I?) the Ruby’s and JS’ Duck type system. On the opposite side in Go you have quite a strong typing, so let’s start with smth small.

Variables assignment
 
In my previous post I used such a construction (ok, it was a bit different, but still):
hello, world := "Hello", "World"

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.
Furthermore, you can also write var hello = "Hello" and it will grasp the type, so it’s not only `:=`’s feature.

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).
In this example, as you may see, we split up the variable definition and the value assignment. Since it’s a variable, we can do this. Now do a couple of experiments:
1. Try to change the first line in function to be const someString string. Then try to run it go run hello.go. Ta-daam, compilation error. If you define a constant, you should instantly assign it. And it makes a lot of sense by me.

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!

Types in Golang
Ok, let’s be cool with it. In general, Go has following type categories: Numbers, Strings, Lists, Booleans.

Booleans
For Booleans no surprises (just the type name is not boolean, but bool), they are just a standard booleans, like true/false with usual boolean algebra rules. Also as in Ruby and JS you have the bang operator, which inverts the variable. You can also use two bangs for double inversion.

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.

String
The next convenient type, String. You already have got familiar with it in the previous post.

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.
There is no proper string interpolation in Golang, so it can be bothersome to deal with it, however there is a way, but we will talk about it in another post.

Numbers
Next type family is Numbers. As usual, it has float and integers. And if in Ruby you just have a generic type and interpreter decides by itself, which type to use, in Golang you should specify it by yourself. And the possible types are:

Integers
int8, int16, int32, int64, uint8, uint16, uint32, uint64
Numbers in these types, as you may understand, represent bits amount, and the prefix ‘u’ on some of them means that it can not be negative (unsigned). If you will try to pass a negative number to your uint variable, it will throw an error constant -10 overflows uint32

Floats
float32, float64. Nothing new here, numbers represent the same. Also as in any other language, numbers with floating points are not round, so this code won’t give you 0.9:

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.

Arrays

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.

Maps
Maps are almost the same as Ruby’s Hashes. Just with one difference. Can you guess, what is the difference? Yeah, u rrright, they are statically typed!

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.


Phew, enough for today. I go on vacation next week, but still, hope to have some time to write one more Golang for Rubyists post before that. Also, just a reminder, I have a youtube channel EverydayDev where I sporadically (actualy quite often) post some short videos about my insights or interesting articles or tools I read about this day. It is a quite laborious process for me, creating even such short videos, so I really appreciate any feedback or likes I’m getting there. So please feel free to check them out as well. I’m glad if this post was useful to you, see you very soon!
基于STM32F407,使用DFS算法实现最短迷宫路径检索,分为三种模式:1.DEBUG模式,2. 训练模式,3. 主程序模式 ,DEBUG模式主要分析bug,测量必要数据,训练模式用于DFS算法训练最短路径,并将最短路径以链表形式存储Flash, 主程序模式从Flash中….zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、习资料等,我会提供帮助,提供资料,鼓励习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等科竞赛比赛、初期项目立项、习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源习/技术交流/习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值