记一次单链表的翻车之旅,go的类型别名与类型声明

最近在学习单链表的时候,在创建完Node节点之后,链表的表示是新建一个struct,如下
```
type List1 struct {
Head *Node
}
```
这样做完全没问题。可是我看的是<<数据结构与算法分析C语言>>版本的,就想着用类似C的typedef来实现下单链表,所以就有了以下代码
```声明一个新类型list2
type list2 *Node
```

这样的类型声明看着完全没问题.继续写,来一个判断单链表是否是空表的方法,很容易写出一下代码。
```
func (l list2) isEmpty() bool {
return l.Next == nil
}
```
但是编译器在这里却报了个错误.
> [go] invalid receiver type list2(list2 is a pointer type)

直译出来就是:因为list2是指针类型,所以这是个无效的方法接受者

在stackoverflow找到这一段解释
> The receiver type must be of the form T or *T where T is a type name. The type denoted by T is called the receiver base type; it must not be a pointer or interface type and it must be declared in the same package as the method.

**大致意思就是在Go中,方法的接受者可以是T或者*T类型的,这里T不能是指针类型或接口类型.**

既然这种类型声明出来的新类型不符合条件,那么我们可以用一下方法写

```
type list2 Node

func (l *list2) isEmpty() bool {
return l.Next == nil
}
```
**这样写虽然可以让代码运行,但是却不符合链表的定义,在<<数据结构与算法分析C语言>>中,C的typedef出来的类型其实是指针类型的,这里只是代码运行无误,却不合乎定义,而且,为了预防调用这使用强制类型转化带来的错误,要慎用这种类型声明**

既然类型申明用不了,那来试试类型命名
> 类型别名和原类型完全一样,只不过是另一种叫法而已

有兴趣的可以看下这篇文章 https://talks.golang.org/2016/refactor.article
> 文章主要讲的是:在大规模的重构项目代码的时候,尤其是将一个类型从一个包移动到另一个包中的时候,有些代码使用新包中的类型,有些代码使用旧包中的类型;类型别名会十分方便、有效

```
type list2 = *Node

func (l list2) isEmpty() bool {
return l.Next == nil
}
```
代码上来看无任何问题,并且链表list也是*Node类型的。可以实现链表的功能。

再来看下go内置的双链表的实现,源码在"container/list"下
```
type Element struct {
next, prev *Element

list *List

Value interface{}
}

type List struct {
root Element
len int
}
```
可以看到go官方的链表也是新建一个新类型出来,并非使用类型命名或者类型定义,而且链表中还自带len字段,在查找链表长度时很方便,不用去遍历来实现链表的长度。

#### 来模仿官方源码来写一个单链表

* **1.无头节点**
```
type list struct {
len int
root *Node
}
```
* **2.有头节点**
带有头节点的单链表也可以有两种写法

* 第一种就是把链表的长度当作链表的字段来存放
```
type list struct {
len int
root *Node
}

```
* 第二种就是链表的长度存放在头节点的数据域中,如数据源是int,int8...等类型的时候
```
type list3 struct {
head *Node
}
```
这里head不能为nil,并且head.Data 存放链表长度,head.Next存放第一个有效的节点



[博客地址](https://github.com/zgjff/Blog/issues/2)


转载于:https://juejin.im/post/5c21a514e51d457f063b8098

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值