请从github下载配套代码: https://github.com/shuningzhang/learn_golang
前面文章本号给大家介绍了基本的数据类型,表达式和函数等内容。有的时候基本的数据类型可能不能满足我们开发的需求,我们可能需要一些数据类型的组合。比如我们要把一个班级里面所有人的平均成绩存在一起,然后计算整个班级的平均成绩。大家想一下,这种情况下应该用什么类型的变量?
数组
接着上面我们举的例子,如果要计算平均成绩怎么办呢?这就用到了数组的概念。数组从字面上理解就是一组数,它是指类型相同的一组数。这组数在内存中是顺序存储的,因此,我们可以通过数组名字的索引来访问其中的数据,而不同定义多个变量。
如图1是数组内部结构的示意图,我们可以通过数组的索引访问数组内部的数据。通常数组的索引是从0开始的,0表示第一个元素。下面我们给出一个Go语言的具体示例:
package main
import "fmt"
/* 这个函数用于计算几个学生成绩的均值 */
func calc_average () (float32) {
var student_1 uint32 = 67
var student_2 uint32 = 89
var student_3 uint32 = 96
var student_4 uint32 = 87
var student_5 uint32 = 79
var sum uint32 = 0
var result float32 = 0;
sum = student_1 + student_2 +
student_3 + student_4 +
student_5
result = float32(sum) / 5
return result
}
/* 上面函数计算均值数据数量少,可能并看不出有
* 多麻烦,如果有100个学生,上面一个函数将会非常
* 复杂。
* 下面这个函数利用了数组,功能是一样的。*/
func calc_average_ex() (float32) {
/* 这里定义一个数组,并进行初始化,初始化不
* 是必须的。
* 数组的名称 数量 类型 数组初始化的数据 。*/
var students = [5] uint32 {67, 89, 96, 87, 79}
var sum uint32 = 0
var result float32 = 0
var i uint32 = 0
/* 通过数组,结合for循环可以非常容易的计算
* 累加和。
* 数组索引是从0开始的,0表示第一个元素。 */
for i = 0; i<5; i++ {
/* 数组的访问通过[]进行,其中i是索引。
* 读或者写其中的值都通过[]访问。 */
sum += students[i]
}
result = float32(sum) / 5
return result
}
func main() {
/* 这里是函数的调用 */
fmt.Println( calc_average_ex() )
}
上面数组数量,如果有初始化的情况下可以不必指定大小,此时编译器会根据初始化的数据数量自动确定大小,具体定义的格式如下:
var students = [...] uint32 {67, 89, 96, 87, 79}
数组的内容还很多,我们这里先学会基本的使用,后续再详细介绍。
结构体
上面数组用于计算非常方便,但是如果我们需要一种数据类型表示学生,比如包含姓名、年龄和分数等,这样就比较难以实现了。这时就可以通过结构体来实现。结构体是对多种数据类型的封装,形成一个新的数据类型,之后我们就可以将该类型作为一种数据类型使用,使用的方式与普通数据类型一样。
package main
import "fmt"
/* 这里是结构体的定义,定义部分包含3部分
* type关键字, 名称 struct关键字。 之后
* 是结构体定义的主体,里面具体的成员定义。
* 成员定义有名称和类型构成。*/
type Student struct {
name string
age uint8
score uint8
}
func main() {
/* 这里是结构体类型的定义,与普通变量无疑 */
var zhang Student
/* 还可以在定义的时候进行初始化 */
var wang = Student{"ericwang", 17, 99}
/* 成员访问, 通过 变量名.成员 进行访问。 */
zhang.name = "sunnyzhang"
zhang.age = 18
zhang.score = 98
/* 获取成员的值 */
fmt.Println( zhang.age, wang.age )
}
接口
在面向对象编程中,可以这么说:“接口定义了对象的行为”, 那么具体的实现行为就取决于对象了。在Go中,接口是一组方法签名。当一个类型为接口中的所有方法提供定义时,它被称为实现该接口。它与oop非常相似。接口指定类型应具有的方法,类型决定如何实现这些方法。下面我们看一个具体的实例:
package main
import "fmt"
/* 这里是接口的定义,定义部分包含3部分
* type关键字, 名称 interface关键字。 之后
* 是接口定义的主体,里面包含该接口具有的
* 方法定义 */
type Student interface {
get_name() string
get_age() uint8
}
/* 这里定义的是结构体的数据类型
* */
type StudentS struct {
name string
age uint32
}
/* 下面是接口的具体实现,对接口的get_name方法
* 进行了实现,并且绑定到了StudentS类型上。
* 这种定义方式与C++和Java的非常不同,这里没有
* this或者self,而是有开发者自己定义。*/
func (student StudentS) get_name () string{
return student.name
}
func main() {
var student = StudentS{"sunnyzhang", 18}
/* 获取成员的值 */
fmt.Println( student.get_name() )
}
好了,今天我们对基本的符合数据类型进行了基本的介绍,大家也基本可以依葫芦画瓢了。后面我们再结合实例进行深入的介绍。
截止到目前,我们通过4篇文章对Go语言的基本语法有了一个基本的认识,后面我们将进入正题,开发我们的Web服务程序。希望通过这些实例能够让大家对Go语言有更加深入的了解。如果有任何问题,也希望大家在下面留言,作者会尽可能详细的回复大家。
有疑问加站长微信联系(非本文作者)