golang开发环境搭建与踩坑记录

news2024/11/16 4:20:37

文章目录

  • 一、安装下载
    • 1、go环境
    • 2、ide
  • 二、基本使用
    • 1、运行
    • 2、结构体与方法函数指针
    • 3、闭包
    • 4、指针
    • 5、map
    • 6、接口
    • 7、异常
  • 三、包管理
    • 1、go mod语法
    • 2、项目下载所有依赖

一、安装下载

1、go环境

下载地址:https://go.dev/dl/
或者:https://golang.google.cn/dl/

在这里插入图片描述
windows直接下载msi文件安装即可。

linux下载之后,进行解压+环境变量设置:

# 下载
wget https://go.dev/dl/go1.22.5.linux-amd64.tar.gz
# 解压
tar -zxvf go1.22.5.linux-amd64.tar.gz
# 进入到go的解压路径
/root/go/go/bin

# 临时环境变量,关闭控制台就失效了
export PATH=$PATH:/root/go/go/bin
# 编辑 ~/.bash_profile 或者 /etc/profile,添加
export PATH=$PATH:/root/go/go/bin
# 环境变量生效
source ~/.bash_profile
# 或
source /etc/profile

# 验证
[root@localhost ~]# go version
go version go1.22.5 linux/amd64

2、ide

GoLand:https://www.jetbrains.com/go/

二、基本使用

1、运行

# 直接运行
go run hello.go
# 编译为可执行文件
go build hello.go 

2、结构体与方法函数指针

package main

import "fmt"

type Books struct {
	/*首字母大写相当于 public。
 	首字母小写相当于 private。
	这个 public 和 private 是相对于包(go 文件首行的 package 后面跟的包名)来说的。

	当要将结构体对象转换为 JSON 时,对象中的属性首字母必须是大写,才能正常转换为 JSON。
	*/
   title string
   author string
   subject string
   book_id int
}

func main() {

	// 创建一个新的结构体
	fmt.Println(Books{"Go 语言", "www.4399.com", "Go 语言教程", 6495407})

	// 也可以使用 key => value 格式
	fmt.Println(Books{title: "Go 语言", author: "www.4399.com", subject: "Go 语言教程", book_id: 6495407})

	// 忽略的字段为 0 或 空
	fmt.Println(Books{title: "Go 语言", author: "www.4399.com"})

   var Book1 Books        /* 声明 Book1 为 Books 类型 */
   var Book2 Books        /* 声明 Book2 为 Books 类型 */

   /* book 1 描述 */
   Book1.title = "Go 语言"
   Book1.author = "www.4399.com"
   Book1.subject = "Go 语言教程"
   Book1.book_id = 6495407

   /* book 2 描述 */
   Book2.title = "Python 教程"
   Book2.author = "www.4399.com"
   Book2.subject = "Python 语言教程"
   Book2.book_id = 6495700

   /* 打印 Book1 信息 */
   printBook(Book1)

   /* 打印 Book2 信息 */
   printBook(Book2)
}

func printBook( book Books ) {
	fmt.Printf( "Book title : %s\n", book.title)
	fmt.Printf( "Book author : %s\n", book.author)
	fmt.Printf( "Book subject : %s\n", book.subject)
	fmt.Printf( "Book book_id : %d\n", book.book_id)
 }
package main

import (
   "fmt"  
)

/* 定义结构体 */
type Circle struct {
  radius float64
}


func main()  { 
   var c Circle
   fmt.Println(c.radius)
   c.radius = 10.00

   // 方法返回值用参数接收 
   area := c.getArea()
   fmt.Println()
   c.changeRadius(20)
   fmt.Println(c.radius)
   change(&c, 30)
   fmt.Println(c.radius)
}
func (c Circle) getArea() float64  {
   return c.radius * c.radius
}
// 注意如果想要更改成功c的值,这里需要传指针
func (c *Circle) changeRadius(radius float64)  {
   c.radius = radius
}

// 以下操作将不生效
//func (c Circle) changeRadius(radius float64)  {
//   c.radius = radius
//}
// 引用类型要想改变值需要传指针
func change(c *Circle, radius float64)  {
   c.radius = radius
}

// 这种是把【Circle类】作 为参数传递,并返回Circle类对象
func getArea2(c Circle) Circle {
	var temp Circle
	temp.radius = c.radius * 12
	return temp
 }
 
 // 这种是返回Circle类对象
 func getArea3() Circle {
	var temp Circle
	temp.radius = 0.999
	return temp
 }

3、闭包

package main

import "fmt"

func getSequence() func() int {
   i := 0
   return func() int {
      i += 1
      return i
   }
}

func main() {
   /* nextNumber 为一个函数,函数 i 为 0 */
   nextNumber := getSequence()

   /* 调用 nextNumber 函数,i 变量自增 1 并返回 */
   fmt.Println(nextNumber()) //这个执行结果是1
   fmt.Println(nextNumber()) //这个执行结果是2
   fmt.Println(nextNumber()) //这个执行结果是3

   /* 创建新的函数 nextNumber1,并查看结果 */
   nextNumber1 := getSequence() //当getSequence()被重新赋值之后,nextNumber的值应该销毁丢失的,但并没有
   fmt.Println(nextNumber1()) //这儿因为是新赋值的,所以是1
   fmt.Println(nextNumber()) //这一行代码是补充上例子的。这儿可不是新赋的值,重点说明这一个,这儿执行居然是4,这个值并没有被销毁,原因就是闭包导致的,尽管外面的函数销毁了,但是内部函数仍然存在,还可以继续走。这个就是闭包
   fmt.Println(nextNumber1()) //新赋值的,继续执行是2
}

4、指针

指针变量只能指向一个地址。
在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。

package main

import "fmt"

func main() {
   var a int= 20   /* 声明实际变量 */
   var ip *int        /* 声明指针变量 */

   ip = &a  /* 指针变量的存储地址 */

   fmt.Printf("a 变量的地址是: %x\n", &a  ) // a 变量的地址是: 20818a220

   /* 指针变量的存储地址 */
   fmt.Printf("ip 变量储存的指针地址: %x\n", ip ) // ip 变量储存的指针地址: 20818a220

   /* 使用指针访问值 */
   fmt.Printf("*ip 变量的值: %d\n", *ip ) // *ip 变量的值: 20
}

多级指针本质上就是一个指针链。

package main

import (
   "fmt"  
)

func main()  { 
	var a int = 5
    // 指针
    var p1 *int = &a
    // 二级指针
    var p2 **int = &p1
    // 三级指针
    var p3 ***int = &p2

    fmt.Printf("p1的值:%d    p1的目标值:%d\n", p1, *p1) // p1的值:824633761992    p1的目标值:5
    fmt.Printf("p2的值:%d    p2的目标值:%d    p2的链尾目标值:%d\n", p2, *p2, **p2) // p2的值:824634196008    p2的目标值:824633761992    p2的链尾目标值:5
    fmt.Printf("p3的值:%d    p3的目标值:%d    下一个目标值:%d    p3的链尾目标值:%d\n", p3, *p3, **p3, ***p3) // p3的值:824634196016    p3的目标值:824634196008    下一个目标值:824633761992    p3的链尾目标值:5
   
}

向函数传递指针:

package main

import "fmt"

func main() {
   /* 定义局部变量 */
   var a int = 100
   var b int= 200

   fmt.Printf("交换前 a 的值 : %d\n", a )
   fmt.Printf("交换前 b 的值 : %d\n", b )

   /* 调用函数用于交换值
   * &a 指向 a 变量的地址
   * &b 指向 b 变量的地址
   */
   swap(&a, &b);

   fmt.Printf("交换后 a 的值 : %d\n", a )
   fmt.Printf("交换后 b 的值 : %d\n", b )
}

func swap(x *int, y *int) {
   var temp int
   temp = *x    /* 保存 x 地址的值 */
   *x = *y      /* 将 y 赋值给 x */
   *y = temp    /* 将 temp 赋值给 y */
   // *x, *y = *y, *x 可以优化为这个
}

5、map

package main

import "fmt"

/*
使用 make 函数  其中 KeyType 是键的类型,ValueType 是值的类型,initialCapacity 是可选的参数,用于指定 Map 的初始容量。
map_variable := make(map[KeyType]ValueType, initialCapacity)
*/

func main() {

	// 创建一个空的 Map
	m := make(map[string]int)

	// 创建一个初始容量为 10 的 Map
	m := make(map[string]int, 10)

	// 使用字面量创建 Map
	m := map[string]int{
		"apple": 1,
		"banana": 2,
		"orange": 3,
	}

	// 获取键值对
	v1 := m["apple"]
	v2, ok := m["pear"]  // 如果键不存在,ok 的值为 false,v2 的值为该类型的零值

	// 修改键值对
	m["apple"] = 5

	// 获取 Map 的长度
	len := len(m)

	// 遍历 Map
	for k, v := range m {
		fmt.Printf("key=%s, value=%d\n", k, v)
	}

	// 删除键值对
	delete(m, "banana")



}

6、接口

package main

import "fmt"

type Shape interface {
    area() float64
}

type Rectangle struct {
    width  float64
    height float64
}

func (r Rectangle) area() float64 {
    return r.width * r.height
}

type Circle struct {
    radius float64
}

func (c Circle) area() float64 {
    return 3.14 * c.radius * c.radius
}

func main() {
    var s Shape

    s = Rectangle{width: 10, height: 5}
    fmt.Printf("矩形面积: %f\n", s.area())

    s = Circle{radius: 3}
    fmt.Printf("圆形面积: %f\n", s.area())
}

7、异常

error 类型是一个接口类型,这是它的定义:

type error interface {
    Error() string
}

我们可以在编码中通过实现 error 接口类型来生成错误信息。

函数通常在最后的返回值中返回错误信息。使用 errors.New 可返回一个错误信息:

func Sqrt(f float64) (float64, error) {
    if f < 0 {
        return 0, errors.New("math: square root of negative number")
    }
    // 实现
}

示例:

package main

import (
    "fmt"
)

// 自定义错误信息结构
type DIV_ERR struct {   
    etype int  // 错误类型   
    v1 int     // 记录下出错时的除数、被除数   
    v2 int
}
// 实现接口方法 error.Error()
func (div_err DIV_ERR) Error() string {   
    if 0==div_err.etype {      
        return "除零错误"   
    }else{   
        return "其他未知错误"  
    }
}
// 除法
func div(a int, b int) (int,*DIV_ERR) {  
    if b == 0 {     
        // 返回错误信息    
        return 0,&DIV_ERR{0,a,b}  
    } else {   
        // 返回正确的商  
        return a / b, nil   
    }
}
func main() { 
    // 正确调用  
    v,r :=div(100,2)  
    if nil!=r{   
        fmt.Println("(1)fail:",r)  
    }else{   
        fmt.Println("(1)succeed:",v) 
    }   
    // 错误调用
    v,r =div(100,0) 
    if nil!=r{   
        fmt.Println("(2)fail:",r)  
    }else{  
        fmt.Println("(2)succeed:",v) 
    }
}

三、包管理

1、go mod语法

# 新建项目
mkdir myapp && cd myapp
# 初始化项目,生成go.mod
go mod init myapp

# 指定国内包源地址
go env -w GOPROXY=https://goproxy.cn
# 下载echo包
go get github.com/labstack/echo/v4

#  更新依赖
go get -u xxx

# 删除项目中没有用到的依赖包
go mod tidy

# 查看当前项目依赖包
go list

2、项目下载所有依赖

## 第一步
go mod download 
## 第二步
go mod tidy
## 第三步
go list -m -json all
## 第四步
go mod vendor

## 执行完以上操作后,如果项目引入包爆红,或者项目可以正常运行,但引入的包报红,则执行以下方法。
## 第一步
go mod tidy
## 第二步
go mod vendor

要是还是不行(一般来说到第2步就可以了): 打开 GoLand 点击左上角: File–>Setting–>Go–>Go Modules–>Enable Go modules integration, 一般来说这样就可以了
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1935308.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

19.x86游戏实战-创建MFC动态链接库

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

向量数据库选择浅谈

初见大模型 作为新手接触大模型后&#xff0c;LLM模型、Embedding模型、rank模型、vector模型等等选择上可谓是一步一个坑&#xff0c;迷茫的走在迷茫的大路上。总之各种途径去选择合适的模型&#xff0c;今天了解下向量数据库选择依据。 借鉴前人 学习之前先看看大家都在关注…

基于java+springboot+vue实现的中小企业人事管理系统(文末源码+Lw)128

基于SpringBootVue的实现的中小企业人事管理系统&#xff08;源码数据库万字Lun文流程图ER图结构图ppt演示视频软件包&#xff09; 系统角色&#xff1a; 员工、管理员 系统功能&#xff1a; 管理员登录 进入中小企业人事管理系统可以查看首页、个人中心、员工管理、部门信息管…

arthas监控本地耗时代码(windows)

1、安装 curl -O https://arthas.aliyun.com/arthas-boot.jar 2、运行 java -jar arthas-boot.jar 3、选择监控的程序端口 运行后如下&#xff1a;第二个是我的后端程序&#xff0c;我选择2后回车 4、监控代码块 trace com.example.demo.service.impl.LoginServiceImp…

Docker 镜像使用和安装

​ 1、简介 Docker是一个开源的应用容器引擎&#xff1b;是一个轻量级容器技术&#xff1b; Docker支持将软件编译成一个镜像&#xff1b;然后在镜像中各种软件做好配置&#xff0c;将镜像发布出去&#xff0c;其他使用者可以直接使用这个镜像&#xff1b; 运行中的这个镜像…

Java面试八股之Redis怎么实现消息队列

Redis怎么实现消息队列 Redis实现消息队列主要依赖于其内置的数据结构&#xff0c;如List、Pub/Sub&#xff08;发布/订阅&#xff09;和Stream。下面将分别介绍这三种方式及其特点&#xff1a; 1. List实现消息队列 Redis的List是一个双向链表&#xff0c;支持快速的头部和…

【学术会议征稿】第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024)

第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024) 2024 6th International Conference on Frontier Technologies of Information and Computer 第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024)将在中国青岛举行&#xff0c;会期是2024年11月8-10日&#xff0c;为…

Python面试宝典第15题:岛屿数量

题目 在二维网格地图上&#xff0c;1 表示陆地&#xff0c;0 表示水域。如果相邻的陆地可以水平或垂直连接&#xff0c;则它们属于同一块岛屿。请进行编码&#xff0c;统计地图上的岛屿数量。比如&#xff1a;下面的二维网格地图&#xff0c;其岛屿数量为3。 基础知识 解决这类…

Linux入门以及Linux文件编程学习

Linux学习必备 首先我们学习Linux必须安装一个虚拟机&#xff0c;我是跟着韦东山老师安装的&#xff0c;具体可以跟着视频操作&#xff0c;简单易懂&#xff1a;安装虚拟机 Linux入门最基本简单的指令 一、Vi的使用 Vi文件名 创建或者打开一个文件&#xff0c;进入默认命令行…

[论文笔记] pai-megatron-patch Qwen2-CT 长文本rope改yarn

更改: # Copyright (c) 2024 Alibaba PAI and Nvidia Megatron-LM Team. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License a…

Linux——多路复用之select

目录 前言 一、select的认识 二、select的接口 三、select的使用 四、select的优缺点 前言 在前面&#xff0c;我们学习了五种IO模型&#xff0c;对IO有了基本的认识&#xff0c;知道了select效率很高&#xff0c;可以等待多个文件描述符&#xff0c;那他是如何等待的呢&a…

JavaScript 获取 url(get)参数

https://andi.cn/page/621584.html

Gitee 使用教程1-SSH 公钥设置

一、生成 SSH 公钥 1、打开终端&#xff08;Windows PowerShell 或 Git Bash&#xff09;&#xff0c;通过命令 ssh-keygen 生成 SSH Key&#xff1a; ssh-keygen -t ed25519 -C "Gitee SSH Key" 随后摁三次回车键&#xff08;Enter&#xff09; 2、查看生成的 SSH…

大鲸鱼docker-compose单机容器集群编排工具

目录 一、Docker-compose 概述 二、Docker-compose简介 三、YML文件格式及编写注意事项 1.yml文件是什么 2.yml问价使用注意事项 3.yml文件的基本数据结构 四、Docker-compose 配置 1.Docker-Compose 配置常用字段 2.Docker Compose常用命令 3.使用Docker-compose创建…

Python解释器:CPython 解释器

一、什么是python解释器 Python解释器是一种用于执行Python代码的程序。 它将Python源代码转换为机器语言或字节码&#xff0c;从而使计算机能够执行。 1.1 Python解释器分类 1、CPython CPython 是 Python 的主要实现&#xff0c;由 C 语言编写。大多数用户在日常开发中使…

django实现用户的注册、登录、注销功能

创建django项目的步骤&#xff1a;Django项目的创建步骤-CSDN博客 一、前置工作 配置数据库&#xff0c;设置数据库引擎为mysql 1、在settings文件中找到DATABASES, 配置以下内容 DATABASES {"default": {ENGINE: django.db.backends.mysql, # 数据库引擎NAME: dja…

色彩与故乡的对话 —— 钱华个人油画展正式开展

色彩与故乡的对话 —— 钱华个人油画展正式开展 2024年7月17日 &#xff0c;在宁波这座历史与现代交织的城市里&#xff0c;艺术与文化的碰撞再次绽放出耀眼的光芒。由宁波海曙区美术家协会主办&#xff0c;宁波市海纳广场开发经营有限公司协办的“色彩与故乡的对话——钱华个人…

【SpringBoot Web开发之静态资源访问】笔记

详细内容见官方文档&#xff1a;Static Content SpringBoot Web开发之静态资源访问 1.准备工作&#xff1a;创建WebDemo2.静态资源目录2.1官网原文2.2静态资源目录第一步&#xff1a;依照上面2.1官网原文中创建如下目录第二步&#xff1a;复制粘贴图片到静态资源目录中第三步…

二叉树的前、中、后序遍历(递归法、迭代法)leetcode144/94/145

leetcode144、二叉树的前序遍历 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a;…

海外媒体发稿-瑞典SEO破茧成蝶:从0到10的实战精要-大舍传媒

海外媒体发稿-瑞典SEO破茧成蝶:从0到10的实战精要 一、迷茫与意义的探寻 有一天我找了王老师聊天&#xff0c;谈到生活迷茫和人生的意义。老师说了一段话&#xff1a;当全情投入于一件事情时&#xff0c;是没有时间去迷茫或思索人生意义的。我感触很深&#xff0c;当总感到迷…