golang 基础线

seven_son · · 962 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

go结构体详解

go 是面向对象语言

封装

  • 状态 (属性)

  • 行为 (方法)

可见性/不可见性 (大写/小写)

可重用性

  • 继承 (组合)

方法的重载

  • 多态

接口

  • 传统没,面向对象编程语言

  • 数据结构构成一个类

  • 你可以创建一个对象通过类的模板

  • 类中封装了属性和方法

go中的类型

Go 类型:基本类型、引用类型、结构类型、自定义类型

Go 语言中,引用类型有 切片、字典(map)、接口、函数类型 以及 通道(chan) 。

结构类型是用来描述一组值的,比如一个人有身高、体重、名字和年龄等,本质上是一种聚合型的数据类型

类型别名 Go 的编译器不会像 Java 的那样,帮我们做隐式的类型转换。

package main
import "fmt"
type foo int
func main() {
    var myAge foo
    myAge = 44
    fmt.Printf("%T %v \n", myAge, myAge)
}

结构体的初始化

type person struct {
    first string
    last  string
    age   int
}
func main() {
    p1 := person{"James", "Bond", 20}
    p2 := person{"Miss", "Moneypenny", 18}
    fmt.Println(p1.first, p1.last, p1.age)
    fmt.Println(p2.first, p2.last, p2.age)
}

struct method 结构体的方法

type person struct {
    first string
    last  string
    age   int
}

func (p person) fullName() string {
    return p.first + p.last
}

func main() {
    p1 := person{"James", "Bond", 20}
    p2 := person{"Miss", "Moneypenny", 18}
    fmt.Println(p1.fullName())
    fmt.Println(p2.fullName())
}

组合类型 嵌入式类型

type person struct {
    First string
    Last  string
    Age   int
}

type doubleZero struct {
    person
    LicenseToKill bool
}

func main() {
    p1 := doubleZero{
        person: person{
            First: "James",
            Last:  "Bond",
            Age:   20,
        },
        LicenseToKill: true,
    }

    p2 := doubleZero{
        person: person{
            First: "Miss",
            Last:  "MoneyPenny",
            Age:   19,
        },
        LicenseToKill: false,
    }

    fmt.Println(p1.First, p1.Last, p1.Age, p1.LicenseToKill)
    fmt.Println(p2.person.First, p2.Last, p2.Age, p2.LicenseToKill)

属性方法的覆盖

声明一个结构体类型的类型,若发生类型嵌套,如果外层没有内层的属性和方法则可以直接拿到内层的属性和方法
如果外层也声明了一样的熟悉和方法,则会发生覆盖,这跟面向对象的重写类似,在go中嵌套就是传统面向对象的继承

结构体的指针

结构体的指针可以改变该结构体的属性和方法
```go
type person struct {
name string
age int
}

func main() {
p1 := &person{"James", 20}
fmt.Println(p1)
fmt.Printf("%T\n", p1)
fmt.Println(p1.name)
fmt.Println(p1.age)
}

#### 结构体序列化
>结构体的属性要大写,不然不能够序列化


```go
type person struct {
    First       string
    Last        string
    Age         int
    notExported int
}

func main() {
    p1 := person{"James", "Bond", 20, 007}
    bs, _ := json.Marshal(p1)
    fmt.Println(bs)
    fmt.Printf("%T \n", bs)
    fmt.Println(string(bs))
}

变量作用域

包的变量

var x = 42

func main() {
    fmt.Println(x)
    foo()
}

func foo() {
    fmt.Println(x)
}

包变量的作用域及可导出

在go中 变量或方法名为大写则意味着可导出,在同一个包中可以任意使用

// MyName is exported because it starts with a capital letter
var MyName = "Todd"
var yourName = "Future Rock Star Programmer"

变量在方法的作用域

func main() {
    x := 42
    fmt.Println(x)
    foo()
}
func foo() {
    // no access to x
    // this does not compile
    fmt.Println(x)
}

go的变量作用域

go的变量作用域是花括号确定的,任一变量的作用域只在自身所处的花括号范围内
if, for等可以有初始化表达式的,其作用域还要高于其后的花括号一层

闭包

if-else

普通if-else

if a==1{
fmt.Println("a=1")
}

if else 局部变量

       if food := "Chocolate"; b {
        a := true
        if a {
            food := "banana"
            fmt.Println(food)
        } else {
            food := "apple"
            fmt.Println(food)
        }
        fmt.Println(food)
    }

if else else if else

   if false {
        fmt.Println("first print statement")
    } else if true {
        fmt.Println("second print statement")
    } else {
        fmt.Println("third print statement")
    }

循环

for 循环

for i := 0; i <= 100; i++ {
        fmt.Println(i)
    }

for range

当用于遍历数组和切片的时候,range函数返回索引和元素;
当用于遍历字典的时候,range函数返回字典的键和值。

数组

普通数组

var a [23]int
fmt.Println(x)
    fmt.Println(len(x))
    fmt.Println(x[42])
    x[42] = 777
    fmt.Println(x[42])

字面量数组

[3]int [4]int是两种完全不同的类型

var q [3]int = [3]int{1, 2, 3}
var r [3]int = [...]int{1, 2, 4}

切片

mySlice := []int{1, 3, 5, 7, 9, 11}

字典

make与 new的区别

接口

没有接口的解构体方法

type square struct {
    side float64
}

func (z square) area() float64 {
    return z.side * z.side
}

func main() {
    s := square{10}
    fmt.Println("Area: ", s.area())
}

有接口的结构体方法

type square struct {
    side float64
}
func (z square) area() float64 {
    return z.side * z.side
}
type shape interface {
    area() float64
}
func info(z shape) {
    fmt.Println(z)
    fmt.Println(z.area())
}
func main() {
    s := square{10}
    fmt.Printf("%T\n",s)
    info(s)
}

错误处理

发生错误没有进行异常处理

程序发生异常错误 fmt打印
```go
_, err := os.Open("no-file.txt")
if err != nil {
fmt.Println("err happened", err)

}
#### 发生错误没有进行异常处理
>程序发生异常错误 log打印
```go
    _, err := os.Open("no-file.txt")
    if err != nil {
        //        fmt.Println("err happened", err)
        log.Println("err happened", err)
        //        log.Fatalln(err)
        //        panic(err)
    }

发生错误没有进行异常处理

程序发生异常错误 log打印到文本里面

func init() {
    nf, err := os.Create("log.txt")
    if err != nil {
        fmt.Println(err)
    }
    log.SetOutput(nf)
}
func main() {
    _, err := os.Open("no-file.txt")
    if err != nil {
        //        fmt.Println("err happened", err)
        log.Println("err happened", err)
        //        log.Fatalln(err)
        //        panic(err)
    }
}

异常处理函数

defer 表示永远在执行完成去执行defer后面的函数

func clean(){
    fmt.Println(" do something in clean ")
}

func main(){
    defer clean()
    fmt.Println("end main")
}

defer

(基本功能)简单来讲,在defer所在函数执行完所有的代码之后,会自动执行defer的这个函数。
```go
func main() {
defer second()
first()
}

func first() {
fmt.Println("first")
}

func second() {
fmt.Println("second")
}
first
second

>局部函数
```go
func main() {
    defer second()
    defer third()
    first()
}

func first() {
    fmt.Println("first")
}

func second() {
    fmt.Println("second")
}

func third() {
    fmt.Println("third")
}

栈特性
```go
func main() {
defer second()
defer third()
first()
}

func first() {
fmt.Println("first")
}

func second() {
fmt.Println("second")
}

func third() {
fmt.Println("third")
}

>
### panic
>panic相当于一个运行时异常
>遇到panic的时候,会停止当前函数剩下来的语句,但在退出该函数之前,会执行defer的语句
>依据函数调用层次,panic依次终止每个函数,直至main()。





### recover
>recover相当于try-catch的catch部分,使得panic不再传递。而defer相当于try-catch-final的final部分。
```go
func main() {
    f()
}

func final_print(msg string) {
    fmt.Println(msg)
}
func f() {
    fmt.Println("f.1")
    g()
    fmt.Println("f.2")
}
func g() {
    defer func() {
          str := recover()
          fmt.Println(str)
    }()
    defer final_print("g.defer()")
    fmt.Println("g.1")
    h()
    fmt.Println("g.2")
}
func h() {
    defer final_print("h.defer()")
    fmt.Println("h.1")
    panic("panic in h()")
    fmt.Println("h.2")
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:seven_son

查看原文:golang 基础线

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

962 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传