go语言入门

我是搞JAVA的,所以下面主要说明go和java不一样的地方

语言结构

package main

import "fmt"

func main() {
   /* 这是我的第一个简单的程序 */
   fmt.Println("Hello, World!")
}

注意:

  1. 有且只有一个main的package、main方法;

  1. 每行的结束可以不用;

  1. { 不能单独出现在一行;

  1. 使用【import _ 包名】来引用该包,仅仅是为了调用该包中的 init() 函数,所以无法通过包名来调用包中的其他函数

变量

  1. 以下3种定义变量的方式是等价的:

var name string = "wang"

var name = "wang"

name := "wang"

  1. 声明多个变量:

var b, c int = 1, 2

b, c := 1, 2

  1. 常量

const b = true

注意:

  1. 全局变量定义后,可以不使用;但局部变量定义后必须使用,否则编译会报错

  2. 如果变量名首字母大写,则可以被外部包引入(类似于java的public),否则只能在本包内使用;

  3. 第一个字符必须是字母或下划线而不能是数字

循环控制

  1. 普通for循环

for i := 0; i < 10; i ++ {
    fmt.Println(i)
}
i := 1
for i < 10 {
    fmt.Println(i)
}
// 死循环
for {
    fmt.Println("a")
}
  1. range循环针对数组

strings := []string{"a", "b"}
for k, v := range strings {
    fmt.Println(k, v)
}
strings := []string{"a", "b"}
// 只输出key
for k := range strings {
    fmt.Println(k)
}
strings := []string{"a", "b"}
// 只输出value
for _, v := range strings {
    fmt.Println(v)
}

函数

  1. 函数名首字母大写,代表其它包可以访问该函数;

  1. 支持多返回值

func swap(x, y string) (string, string) {
    return y, x
}
  1. 在函数定义的最后加上(),代表立即调用该函数

package main

import("fmt")
func main(){
  str :="Alice"
  func(name string){
    fmt.Println("Your name is", name)
   }(str)
}
  1. 函数参数传递有两种方式:

  • 值传递:默认的,即把值复制一份传递到函数,函数里对参数的修改不会影响原值;

func swap(x, y int) int {}
  • 引用传递:即传递引用,函数里对参数的修改会影响原值

func swap(x *int, y *int) {}

init函数

1.init函数可以在所有程序执行开始前被调用,并且每个包下可以有多个init函数
2.init函数先于main函数自动执行
3.每个包中可以有多个init函数,每个包中的源文件中也可以有多个init函数
4.init函数没有输入参数、返回值,也未声明,所以无法引用
5.不同包的init函数按照包导入的依赖关系决定执行顺序
6.无论包被导入多少次,init函数只会被调用一次,也就是只执行一次
7.init函数在代码中不能被显示的调用,不能被引用(赋值给函数变量),否则会出现编译错误
8.导入包不要出现循环依赖,这样会导致程序编译失败
9.Go程序仅仅想要用一个package的init执行,我们可以这样使用:import _ “test_xxxx”,导入包的时候加上下划线就ok了
10.包级别的变量初始化、init函数执行,这两个操作都是在同一个goroutine中调用的,按顺序调用,一次一个包
11.init函数不应该依赖任何在main函数里创建的变量,因为init函数的执行是在main函数之前的
12.在init函数中也可以启动goroutine,也就是在初始化的同时启动新的goroutine,这并不会影响初始化顺序
13.复杂逻辑不建议使用init函数,会增加代码的复杂性,可读性也会下降
14.一个源文件下可以有多个init函数,代码比较长时可以考虑分多个init函数
15.编程时不要依赖init的顺序

指针

func main() {
   var a int= 20   /* 声明实际变量 */
   var ip *int        /* 声明指针变量 */
   ip = &a  /* 指针变量的存储地址 */
   fmt.Printf("a 变量的地址是: %x\n", &a  )
   /* 指针变量的存储地址 */
   fmt.Printf("ip 变量储存的指针地址: %x\n", ip )
   /* 使用指针访问值 */
   fmt.Printf("*ip 变量的值: %d\n", *ip )
}

语言结构体(类似于Java类)

type Books struct {
   title string
   author string
   subject string
   book_id int
}


func main() {
    // 创建一个新的结构体
    fmt.Println(Books{"Go 语言", "www.runoob.com", "Go 语言教程", 6495407})
    // 也可以使用 key => value 格式
    fmt.Println(Books{title: "Go 语言", author: "www.runoob.com", subject: "Go 语言教程", book_id: 6495407})
    // 忽略的字段为 0 或 空
   fmt.Println(Books{title: "Go 语言", author: "www.runoob.com"})
    // 访问结构体成员
    var Books1 = Books{"Go 语言", "www.runoob.com", "Go 语言教程", 6495407}
    fmt.Println(Books1.title)
}

切片(Slice)

Go的数组长度是固定的,切片其实就是可变长度的数组

定义切片:

var s1 []int
s2 := make([]int, 5) // 5是初始长度
s3 := []int{1, 2, 3} // 初始化
s4 := make([]int, 3, 3) // 3是长度,5是容量,容量代表最长可以达到多少
s5 := s3[1,2] // 通过s3初始化s5,1和2是起始位置和结束位置,前闭后开    

Map

var map1 map[string]string
var map2 = make(map[string]string)
map3 := make(map[string]string{"k1":"v1", "k2":"v2"})
map1["key1"] = "value1"
delete(map3, "k1") // 从map3中删除key为k1的数据

接口

直接看示例:

package main

import (
    "fmt"
)

type Phone interface {
    call()
}

type NokiaPhone struct {
}

func (nokiaPhone NokiaPhone) call() {
    fmt.Println("I am Nokia, I can call you!")
}

type IPhone struct {
}

func (iPhone IPhone) call() {
    fmt.Println("I am iPhone, I can call you!")
}

func main() {
    var phone Phone

    phone = new(NokiaPhone)
    phone.call()

    phone = new(IPhone)
    phone.call()

}

定义了接口:Phone,接口有个call方法

下面这段,代表了NokiaPhone实现了Phone接口,所以才可以var phone Phone = new(NokiaPhone),进而调用call()方法

func (nokiaPhone NokiaPhone) call() {
    fmt.Println("I am Nokia, I can call you!")
}

并发

f是函数名,x y z是参数

go f(x, y, z)

通道

select

其它

go.mod

管理go的依赖包,go.mod是在1.11版本引入的,之前是用GOPATH进行依赖包管理的。当配置了GOPATH后,就不能go.mod文件。

执行下面的命令初始化go.mod文件:

go mod init

vendor

go项目可能会依赖外部的文件,在build时会从远端下载这些依赖文件,但有时候又不能连接远端服务器;这时候就需要vendor模式,执行:go mod vendor,代表把go.mod中定义的依赖,下载到vendor目录下,再build时,直接从本地vendor目录下寻找依赖

编译模式

window安装go后,编译模式默认是windows,即编译exe文件,这时的编译是需要gcc的。

可执行以下命令切换到linux编译模式(生成可执行的二进制文件):

set CGO_ENABLED=0
set GOOS=linux

通过 go env确认修改是否成功

监控(pprof)

在go里用profile代表应用的运行情况数据,比如cpu、内存等

Golang 提供了 runtime/pprof 和 net/http/pprof 两种方式来收集profile信息

  • runtime/pprof:适用于一些一次性应用,即应用启动时开启pprof,应用运行结束后生成pprof文件

  • net/http/pprof:如果你的应用是一直运行的,比如 web 应用,那么可以使用 net/http/pprof 库,它能够对 Http 服务进行分析。示例:

import _ "net/http/pprof"
go func() {
    http.ListenAndServe(":6060", nil)
}()

flag

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
大学生参加学科竞赛有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞赛是提高专业知识和技能水平的有效途径。通过参与竞赛,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞赛是提高学生综合能力的一种途径。竞赛项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参赛者具备全面的素质。在竞赛过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞赛可以为学生提供展示自我、树立信心的机会。通过比赛的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞赛对于个人职业发展具有积极的助推作用。在竞赛中脱颖而出的学生通常能够引起企业、研究机构等用人单位的关注。获得竞赛奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值