首页 > 其他分享 >go自学笔记

go自学笔记

时间:2023-01-07 19:33:33浏览次数:62  
标签:set 函数 int fmt 笔记 Println go 自学

自己啃官网, 搞成能用的系统;

]golang语言环境

下载地址:http://go.p2hp.com/#google_vignette

一直下一步安装,完成 cmd: go version看版本,是否安装成功

在文件管理器地址栏 最前面cmd+空格 回车,直接跳到cmd该目录下

]环境变量

GOROOT

系统环境变量 新建 安装golang的地址:

D:\bread\go\Environment

GOPATH 项目本地保存地址:

D:\bread\go\LearningDocuments{目录下建src,pkg,bin文件夹,以后开发用}

系统的 path环境变量 选项 新建一个环境变量: D:\bread\go\Environment\bin

]cmd下go env 查看go相关工作配置

D:\bread\go\LearningDocuments>go env
set GO111MODULE= #
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\85456\AppData\Local\go-build
set GOENV=C:\Users\85456\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\85456\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=D:\bread\go\LearningDocuments #代码存放地址
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=D:\bread\go\Environment #
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=D:\bread\go\Environment\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.17.3
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=NUL
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\85456\AppData\Local\Temp\go-build3762675728=/tmp/go-build -gno-record-gcc-switches

]txt 运行

在 hello.go目录的cmd 中 go run hello.go文件夹;

编译器 GoLand jetbrain大礼包

破解: https://www.bilibili.com/read/cv19022444 方法

激活码:https://docs.qq.com/doc/DZWFmak1WcVBhdENu

破解软件:D:\bread\go\jihuo-tool

语法开始

package main //main 包

import "fmt" //输出工具

func main() {//无结尾符号 ,英文双引号; 程序入口
fmt.Println("Hello, World!")
}

]注释

单行//

多行/* */

格式字符串 输入输出

//输出打印 格式化字符串,fmt.Printf()

字符串的占位符:

%d 数字, %p 内存地址, %t布尔类型? ,\n换行 , %f 浮点数,%.1f5舍6入保留一位小数,%s字符串的占位符; %T 变量类型; %v切片
//获取变量地址 &变量名 取地址符:&

输出

fmt.Println(name, age)//输出完换行
fmt.Printf("类型:%T,值%s\n", s1, s1)//格式化输出
fmt.Print()输出不换行

输入

获取输入 fmt.Scanln();//接收输入 换行结束

fmt.Scan(&a);//获取a变量的地址,接收输入数据,赋值给变量a

fmt.Scanf();

遇到scan() 程序阻塞等待键盘输入

]变量

X. 声明/定义,初始化赋值 语法

显式声明

var name string = "lu"

var 变量名 数据类型 = 变量值

静态语言类型 必须显示声明变量类型

定义了变量一定要用,否则报错

一次定义多个变量

//声明多个变量
	//1.一行声明多个变量,类型必须一样
	var var4, var5, var6 string="ww" ,"22","rr"
	fmt.Println(var4, var5, var6)
	var var1, var2, var3 int //声明但未赋值,系统自动初始化类型的默认值,
	fmt.Println(var1, var2, var3)
	//2.var()一次,多行声明多个变量,类型可以不一样
	var (
		sex      string  //声明但不赋初始值,  系统会赋类型的初始值,string 空字符串 ""
		high     int     //默认值0
		isFemale bool    //默认 false
		xiongWei float64 //0.0
		//切片, 函数,指针变量的默认未null
	)
	fmt.Println(sex, high, isFemale, xiongWei)

var var7,var8 bool
var7 = var8 =false 不能这样写
	var7=false
		var8=false

变量命名 驼峰

x.短变量声明并初始化

x.短变量声明并初始化, 自动推断变量类型:

限制: 不能提供数据类型; 定义/声明时必须初始化; 只能用在函数内部, 已经定义过的变量不能用这个语法

	name2 := "露露"
	age1 := 30
	fmt.Println(name2, age1)

打印变量类型 %T

fmt.Printf("%T",%T", name2, age1) //%T表示type

打印变量地址

打印变量地址 变量值变了,但是内存地址不会变. 每次启动机器会重新分配新地址.

//输出打印 格式化字符串,fmt.Printf()   字符串的占位符 %d 数字, %p 内存地址  %t布尔类型? \n换行  %f 浮点数
//获取变量地址 &变量名   取地址符:&
	age1 := 30
fmt.Println("数字:%d,内存:%p", age1, &age1)
//数字:string,内存int数字:30,内存0xc00001a088
	age1 = 200
fmt.Printf("数字:%d,内存:%p", age1, &age1)
//数字:200,内存0xc00001a088

交换变量

其他:需要中间变量 C#/java/C等 a, b, temp temp=a a=b b=temp

//变量交换
var a int = 100
var b int = 200
b, a = a, b
fmt.Println(a, b)

匿名变量

'_' 空白标识符 ,任何类型都可以赋值给他, 但是任何赋值给这个变量的值都将被抛弃, 不占内存空间,不分配内存;

用处:接收多个返回值时,如只需要部分,其他的就用'_'代替,抛弃.

变量的作用域

变量,常量,函数的作用范围

局部变量

一般:函数体内声明的变量 var name string="张三"

全局变量

main()函数外定义的变量,

局部变量会覆盖同名的全局变量

常量

显示定义

隐式定义 ,可省略类型,可以推断常量的类型

可一行同时定义多个常量.这样写,必须都赋值,类型可以不一样

一次定义多个常量,const()多行写法 ,

第一行的常量必须赋值(值可以是string,int,bool,iota(特殊的常量,值是int)).

后面行的常量可以不赋值,不赋值值时,默认和上一行常量的值一样.

iota一个特殊系统常量. 一个const定义中常量的行索引.

每次遇到const关键字,系统都将iota的值设为0, 0索引行,

const内每加一行常量定义,iota的值都+1, 1索引行,2索引行... 可以叫 const中的常量行计数器.

//常量
	const c1 string = "存款100万"        //显示定义
	const c2 = 100                       //隐式定义,可以推断常量的类型
	const c3, c4, c5 = "str", 100, false //一行同时定义多个常量.这样写,必须都赋值
	fmt.Println(c3, c4, c5)

	const c6, c7, c8 = "steel", iota, iota ////iota一个特殊系统常量. 一个const定义中常量的行索引.
	// 每次遇到const关键字,系统都将iota的值设为0, 0索引行,const内每加一行常量定义,iota的值都+1, 1索引行,2索引行...
	fmt.Println(c6, c7, c8) //steel,0,0  第0行常量
	const (
		c9  = 10 //const()写法,定义多个常量时,第一行的常量必须赋值.
		c10      //不赋值值时,默认和上一个常量的值一样
		c11
		c12 = "str"
		c13
	)
	fmt.Println(c9, c10, c11, c12, c13) //10 10 10 str str
	const (
		c14 = iota  // 0索引行
		c15         // 不赋值值时,默认和上一行常量的值一样 此处就是iota, 值是1. 行索引为1.  等效于 c15=iota.
		c16         //每加一行 iota都+1
		c17 = "str" ////每加一行 iota都+1
		c18
		c19 = iota ////每加一行 iota都+1  5索引行
		c20        //6索引行

	)
	fmt.Println(c14, c15, c16, c17, c18, c19, c20) //0 1 2 str str 5 6

var name string ="lu"

var s1, s2,s3 int = 1,2,3

var s4, s5 string

s4="tr"

s5="bb"

var (

v1 string

v2 int

v3 bool

)

数据类型

值类型:

引用类型:切片,

布尔类型

var isFlag bool
	fmt.Println("布尔值的默认值:", isFlag)//false

数字型

//整型
var nian int = 18 //默认int64,默认值0  uint无符号  
fmt.Printf("类型:%T,值%d\n", nian, nian)
//浮点型  一般不用来计算;
var cai float64 = 30.26 //默认float64,默认值0.000000 六位, 七位小数时float32会丢失精度;
fmt.Printf("类型:%T,值%f\n", cai, cai)
fmt.Printf("类型:%T,值%.1f\n", cai, cai) //格式可以,控制小数位数,  4,5舍 6入 什么规则?就近?
//别名 byte:uint8,rune:int32,int:int64

字符串

> 字符串在go中是值类型   数组也是值类型
//别名 byte:uint8,rune:int32,int:int64
//string类型 go的字符串是由单个字节连接起来的,go语言的字符串的字节使用UTF-8编码标识的Unicode文本
//字符 '' 字符--整型 映射表:ASCII字符码; GBK中文编码; Unicode 世界统一编码. 取字符的数字类型值,就是编码表中的值
    ch1 := 'A'
	fmt.Printf("类型:%T,值%d\n", ch1, ch1) //类型:int32,值65
	fmt.Println(ch1)//65
	s1 := "A" //字符
	fmt.Printf("类型:%T,值%s\n", s1, s1)//类型:string,值A

//字符串连接 +
fmt.Println("hello" + "田野")
//转义字符 \  
// \" \n换行;\t制表符

字符

var bcha int32 = 'B'
	fmt.Println(bcha)//66

类型转换

//数据类型转换:  必须显示声明
//转换后的变量 := 要转换的类型(变量)
a_t := 3
b_t := 5.00
c_t := float64(a_t)
d_t := int(b_t)
fmt.Printf("类型:%T\n", c_t)
fmt.Printf("类型:%T\n", d_t)
//整型...是不能转换为bool类型的
//同样注意精度丢失的问题;

指针

​ Go 拥有指针。指针保存了值的内存地址[A pointer holds the memory address of a value.]。 通过指针就能获得值

​ 类型 *T 是指向 T 类型值的指针。其零值为 nil[**The type *T is a pointer to a T value. Its zero value is nil. **]。

var p *int
var s_p *string

& 操作符会生成一个指向其操作数的指针[**The & operator generates a pointer to its operand. **]。

i := 42
p = &i
s := "字符串"
s_p = &s
fmt.Println("s的指针s_p,值:", s_p)

* 操作符表示指针指向的底层值[The * operator denotes the pointer's underlying value.]。

fmt.Println(*p) // 通过指针 p 读取 i
*p = 21         // 通过指针 p 设置 i
fmt.Println("利用*+指针变量读取 指针指向的底层值:", *s_p) //指针指向的底层值,  即内存中实际数据的值;
	*s_p = "新字符串"                             //也可以利用来赋值
	fmt.Println("利用*+指针变量读取, 指针指向的底层值:", *s_p)

​ 这也就是通常所说的“间接引用”或“重定向”。

​ [类型T的变量b, &b获取变量b的指针变量p , *p *操作符+p指针变量,读取指针底层]与 C 不同,Go 没有指针运算。

结构体

​ 一个结构体(struct)就是一组字段(field)。

type Vertex struct {
	X int
	Y int
}

func main() {
	fmt.Println(Vertex{1, 2})//V: {1 2}
}

结构体字段

​ 结构体字段使用点号来访问。

v := V{3, 4}
	fmt.Println("结构体字段v.X:", v.X)

结构体指针

​ 结构体字段可以通过结构体指针来访问。

​ 如果我们有一个指向结构体的指针 p,那么可以通过 (*p).X 来访问其字段 X。不过这么写太啰嗦了,所以语言也允许我们使用隐式间接引用,直接写 p.X 就可以。

	var v_p *V
	v_p = &v //结构体 实例 的指针  &{3 4}
	fmt.Println("结构体 实例 的指针:", v_p)
	fmt.Println("用结构的指针访问结构字段:", (*v_p).X)
	fmt.Println("用结构的指针访问结构字段:", v_p.X) //隐式间接访问

结构体文法

​ 结构体文法通过直接列出字段的值来新分配一个结构体。

​ 使用 Name: 语法可以仅列出部分字段。(字段名的顺序无关。)

​ 特殊的前缀 & 返回一个指向结构体的指针。

type Vertex struct {
   X, Y int
}

var (
   v1 = Vertex{1, 2}  // 创建一个 Vertex 类型的结构体
   v2 = Vertex{X: 1}  // 创建一个 Vertex 类型的结构体
   v3 = Vertex{}      // X:0 Y:0
   p  = &Vertex{1, 2} // 创建一个 *Vertex 类型的结构体(指针)
)

func main() {
   fmt.Println(v1, p, v2, v3)
}

数组

类型 [n]T 表示拥有 nT 类型的值的数组。[注意书写语法:最后一个元素换行时的,]

数组的长度是其类型的一部分,因此数组不能改变大小。

var sa [2]string
sa[0] = "2022"
sa[1] = "世界杯"
fmt.Println(sa[0], sa[1])//[2022 世界杯]
fmt.Println(sa)

si2 := [4]int{1, 2, 3, 4}
	fmt.Println(si2)

[注意书写语法:最后一个元素换行时的,]

切片

<切片大小可变

切片大小可变, 数组的灵活视图;A slice, on the other hand, is a dynamically-sized, flexible view into the elements of an array.

​ 类型 []T 表示一个元素类型为 T 的切片。

​ 切片通过两个下标来界定,即一个上界和一个下界,二者以冒号分隔:

a[low : high]

​ 它会选择一个半开区间,包括第一个元素,但排除最后一个元素。

si3 := [6]int{11, 22, 33, 44, 55, 66}
slice1 := si3[0:2]
fmt.Println("si3索引0到2)的切片是:", slice1)

var slice2 []int = []int{11, 22, 33}//语法和数组类似
fmt.Println("切片能实例化吗:", slice2)//可以的. 
可以实例化并赋初始值

<切片可包含任何类型

切片可包含任何类型,甚至包括其它的切片。 当然一次只能包含一种;

// 创建一个井字板(经典游戏)
	board := [][]string{
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
	}

	// 两个玩家轮流打上 X 和 O
	board[0][0] = "X"
	board[2][2] = "O"
	board[1][2] = "X"
	board[1][0] = "O"
	board[0][2] = "X"

	for i := 0; i < len(board); i++ {
		fmt.Printf("%s\n", strings.Join(board[i], " "))
	}

<切片就像数组的引用

​ 切片就像数组的引用.切片并不存储任何数据,它只是描述了底层数组中的一段。

​ 更改切片的元素会修改其底层数组中对应的元素。

​ 与它共享底层数组的切片都会观测到这些修改。

<切片语法

​ 这是一个数组文法:

[3]bool{true, true, false}

​ 下面这样则会创建一个和上面相同的数组,然后构建一个引用了它的切片:

[]bool{true, true, false}

<默认/缺省 上下界

在进行切片时,你可以利用它的默认行为来忽略上下界。

​ 切片下界的默认值为 0,上界则是该切片的长度。

​ 对于数组

var a [10]int

​ 来说,以下切片是等价的:

a[0:10]
a[:10]
a[0:]
a[:]

<切片长度,容量

长度 len(s []T), 切片中元素的个数

容量cap(s []T),从切片下界在底层数组中的索引对应的元素开始, 到底层数组最后一个元素为止,**The capacity of a slice is the number of elements in the underlying array, counting from the first element in the slice. **

s := []int{2, 3, 5, 7, 11, 13}
	printSlice(s)

	// Slice the slice to give it zero length.
	s = s[:0]
	printSlice(s)

	// Extend its length.
	s = s[:4]
	printSlice(s)

	// Drop its first two values.
	s = s[2:]
	printSlice(s)
}

func printSlice(s []int) {
	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}

<nil 切片

​ 切片的零值是 nil

​ nil 切片的长度和容量为 0 且没有底层数组。

var s []int
  fmt.Println(s, len(s), cap(s))//切片的零值nil:[],nil的长度:0,容量:0
  if s == nil {
  	fmt.Println("nil!")
  }

[注意书写语法:最后一个元素换行时的,]

image-20221130010240893

image-20221130010246551

Need a trailing comma before a newline in the composite literal.复合字面值的换行符前需要一个尾随逗号

image-20221130010307836

使用make 创建切片

用 make 创建切片

​ 切片可以用内建函数 make 来创建,这也是你创建动态长度数组的方式。Slices can be created with the built-in make function; this is how you create dynamically-sized arrays.

make 函数会分配一个元素为零值的数组并返回一个引用了它的切片:The make function allocates a zeroed array and returns a slice that refers to that array:

​ 要指定它的容量,需向 make 传入第三个参数:切片类型;切片长度;切片容量

b := make([]int, 0, 5) // len(b)=0, cap(b)=5
b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:]      // len(b)=4, cap(b)=4

算术运算符

+-*/% ++ --

流程语句

if c1124 > 100 {
   fmt.Println("大于100")
} else {
   fmt.Println("小于等于100")
}

Switch

//switch  可以跟任意变量
switch c1124 {
case 60:
   fmt.Println("刚及格")
case 70:
   fmt.Println("70")
case 80, 90:
   fmt.Println("80,.90")
default:
   fmt.Println("兜底条件")
}

//switch不跟变量, 默认true
switch {
case false:
   fmt.Println("false")
case true:
   fmt.Println("true")
default:
   fmt.Println("default")
}

// case 穿透 fallthrough 遇到它时后面的都穿透执行
	//想停止, break
	var e int = 70
	switch e {
	case 60:
		fmt.Println("刚及格")
	case 70:
		fmt.Println("70")
		fallthrough //穿透该层,继续执行下一个case
	case 80:
		//break 就不执行了
		fmt.Println("80")
	case 12:
		fmt.Println("12")
	default:
		fmt.Println("兜底条件")
	}
//for循环  就是没()
for i := 0; i < 5; i++ {
   fmt.Println("打印次数:", i)
}

★函数

//><函数  func 函数名(参数列表) (返回值类型列表){}
func swap(x, y string) (string, string) {
   return y, x
}
func lei(x, y string) (string, int) {
   return y, 2
}

//接收多个返回值
	va1, va2 := swap("你好", "世界")
	fmt.Println(va1, va2)
	va3, va4 := lei("你好", "世界")
	fmt.Println(va3, va4)
	//匿名变量扔掉不要的结果
	va1, _ = swap("nnn", "mmm")

↑特点,返回值,可以多个, 类型可以不一样;接收按顺序

//可变参数 一个函数的参数类型确定,但是个数不确定
func variblePara(a ...int) {
fmt.Println("这是一个可不参数的函数")
}
//可变参数 在 参数列表中的最后一个即可,前面的参数类型可以不同,如下:
func append(s []T, vs ...T) []T

参数传递

值传递:传递的是数据的副本,修改数据对于原始的数据没有影响;

值类型的数据:go的基础类型,array,struct


函数外的变量通过方法的参数传入函数内,在方法内部修改参数,不会改变方法外的变量值. 传入的是值的副本;

对比,引用传递; 操作的是数据的地址: slice ,map, chanel...

切片,可以扩容的数组;

image-20221125225906807

变量作用域

函数内:作用域和其他语言差不多;

特殊之处:

//变量作用域 go特点:if内的作用域
temp := 100
if b125 := 1; b < 10 {
   fmt.Println("if开头定义的局部变量b125:", b125)//1
   temp := 50
   fmt.Println("if中定义的局部变量temp:", temp) //50 就近原则
}
fmt.Println("if外,main函数内的局部变量temp:", temp)//100
//fmt.Println("if开头定义的局部变量b:", b125)// 类似于for

defer函数

go语言中,使用defer关键字来延迟一个函数或者方法的执行.

可以在函数中添加多个defer语句,当函数执行到最后时,这些defer语句会逆序执行

但是当程序执行到defer语句时,go已经把参数传入方法/函数了,只是延缓执行了.

作用:关闭io/网络等资源;

函数的数据类型

函数也是一种数据类型(引用类型) --func()/参数/返回值,不加()函数名就是一个变量

函数在go语言中是复合类型,可以看做是一种特殊的变量

函数名:指向函数体的内存地址,一种特殊类型的指针变量

{//函数类型
    fmt.Printf("f函数的类型是%T:\n", f)//func(int)
	fmt.Println("f指针变量,存着函数体的地址:", f)

	//既然是数据类型,就可以实例化一个对象
	var f2 func(int)
    f2 = f//引用类型的 将f'func(int)函数类型'的变量赋值给实例化的变量f2
    f3 := f//隐式写法也行
    f2(5)//调用f2  和 f()的效果一样
    f3(5)
}
func f(n int) {
	fmt.Println("输入的参数是:", n)
}

匿名函数

func(){}

匿名函数调用:func(){}()

只执行一次

//匿名函数
	//func(a,b int)int{
	//	return a+b
	//}
	//匿名函数调用
	c2210 := func(a, b int) int {
		return a + b
	}(1, 2)
	fmt.Println("调用匿名函数的结果:", c2210)

Go语言支持函数式编程:

1.将匿名函数作为另一个函数的参数(具名函数当然也可以,函数既然是一种类型,就可以当做参数),回调函数

高阶函数调用回调函数,回调函数可以是匿名函数.

2.将匿名函数作为另一个函数的返回值,可以行成闭包结构

//回调函数
	c1126 := oper(1, 2, add)
	fmt.Println("oper回调add的结果是:", c1126)

	c1126 = oper(1, 2, jian)
	fmt.Println("oper回调jian的结果是:", c1126)

	c1126 = oper(8, 2, func(aa, bb int) int {
		if bb == 0 {
			return 0
		} else {
			return aa / bb
		}
	})
	fmt.Println("oper回调匿名函数的结果是:", c1126)

}//main

//函数底层, 匿名函数, 函数作为参数
func oper(a, b int, f func(int, int) int) int { //oper是高阶函数
	return f(a, b) //f是回调函数,可以是匿名函数
}
func add(a, b int) int { //回调函数
	return a + b
}
func jian(a, b int) int { //回调函数
	return a - b
}

gin框架

安装 go get --底层 git clone

安装gin

1、框架文档介绍:go get -u github.com/gin-gonic/gin

2、这时候如果遇到问题资源加载不了,解决方法是使用代理(这块有个 go env 的命令,可以查看当前配置),在cmd中运行

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct

设置后,重新运行 go get -u github.com/gin-gonic/gin 可以很快速的安装

安装后 import "github.com/gin-gonic/gin" 爆红,

settings中的

image-20221126133327297

GOPROXY=https://goproxy.io

就可以用了;

创建服务, 端口, 设置网站,

支持restful api

rest请求方式隔离api

20221228 周三 gin使用

创建服务,,, 给服务指定端口,,,处理请求

-创建新项目

--创建新文件 main.go

package main

import (
	"github.com/gin-gonic/gin"     //引用gin包
	"github.com/thinkerou/favicon" //(4) 编译器会自动下载,牛逼
	"net/http"
)

func main() {
	//20221228三(1)创建一个服务
	ginServer := gin.Default()
	//(4)配置网站图标
	ginServer.Use(favicon.New("./白骷髅.ico")) //ico文件,  ./ 代表项目的相对路径  ico文件放到项目目录下

	//(3)[就可以运行了]访问地址,处理请求,  Request Resopnse
	ginServer.GET("/hello", func(context *gin.Context) {
		context.JSON(200, gin.H{"msg": "返回信息.现在还差写语法基础的知识."})
	}) //后台,返回给前台数据;

	//(5)rest api  开发
	ginServer.POST("/user", func(c *gin.Context) { //c context,   tab键切换输入位置
		c.JSON(200, gin.H{"msg": "测试restfuf POST方式"})
	})
	ginServer.PUT("/user")
	//ginServer.PUT("user")  带不带/都一样
	ginServer.DELETE("/user")

	//20221229(6)加载静态页面
	//(6.0)加载静态页面的函数 搭配 (6.1)使用
	ginServer.LoadHTMLGlob("temp/*") //加载temp文件下所有的静态文件
	//ginServer.LoadHTMLFiles("")//绝对路径 二选一
	//(6.01)加载静态文件的函数
	ginServer.Static("/static", "./static")

	//(6.1)//响应一个页面给前端
	ginServer.GET("/index", func(c *gin.Context) {
		//c.JSON()
		//返回.html页面
		c.HTML(http.StatusOK, "index.html", gin.H{ //gin,H{}  给前台传key:value 的函数
			"msg": "这是go后台传过来的数据.", //!!!注意这个','语法   //前台接收就行 类似vue语法
		})
	})

	//(7)20221230网址传参  接收前端传过来的参数
	// url?userid=zzz&usernanme=菜鸟凤凰   一般传参风格
	ginServer.GET("/user/info", func(c *gin.Context) { //访问网址,   获取请求的上下文,后台处理请求
		uid := c.Query("userid") //获取网址/请求中的参数,  key获得
		uname := c.Query("username")
		c.JSON(200, gin.H{ //返回前台的数据
			"msg":      "这是用传统风格获取的url参数",
			"userid":   uid,
			"username": uname,
		})
	})

	//  /user/info/1/菜鸟凤凰         restful传参风格
	ginServer.GET("user/info/:userid/:username", func(c *gin.Context) {
		uid := c.Param("userid") //获取网址/请求中的参数,  key获得
		uname := c.Param("username")
		c.JSON(http.StatusOK, gin.H{
			"msg":      "这是用restful的传参风格获取的url参数",
			"userid":   uid,
			"username": uname,
		})
	})
	//(2)指定服务端口
	ginServer.Run(":8088")
}

(4)网站图标

image-20221228205025457

goLand 编辑器

厉害痕迹. 恢复文件

image-20221207215636654

恢复,

image-20221207215727609

## 快捷键

标签:set,函数,int,fmt,笔记,Println,go,自学
From: https://www.cnblogs.com/bule911/p/17033326.html

相关文章

  • [概率论与数理统计]笔记:2.5 随机变量函数的分布
    2.5随机变量函数的分布随机变量函数对于一个随机变量\(X\),其取值是不确定的,如果存在一个函数\(g(x)\),使得随机变量\(X,Y\)满足:\[Y=g(X),\]则称随机变量\(Y\)是随机变......
  • 算法学习笔记(50)——记忆化搜索
    记忆化搜索题目链接:AcWing901.滑雪题目描述给定一个\(R\)行\(C\)列的矩阵,表示一个矩形网格滑雪场。矩阵中第\(i\)行第\(j\)列的点表示滑雪场的第\(i\)行......
  • JavaScript学习笔记-in运算符
    in运算符判断是否含有指定的属性  通过运算符可以检查一个对象中是否含有指定的属性,如果有返回true,没有则返回false。语法:  "属性名"in对象实例://创建一个对......
  • 算法学习笔记(49)——树形DP
    树形DP题目链接:AcWing285.没有上司的舞会题目描述Ural大学有\(N\)名职员,编号为\(1∼N\)。他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。每个......
  • FFT(快速傅里叶变换)学习笔记
    前言懒得写前言。希望学到后面的数学知识不要放弃,写在这里督促自己。(作为一个没有接触过复数的萌新)感觉再不学点东西就真的可以退役了。什么是FFT?FFT是一种将多项式......
  • 贝叶斯思维第二版笔记之条件概率
    DataFrameis2-Darray,Seriesis1-Darray例子1:democrat=(gss['partyid']<=1)gssisaDataFramefromCSV,gss['partyid']取出gss这一列,而DataFrame的每一列......
  • .net core操作MongoDB
    前言现实中认识的一个搞java(百万富婆)的大佬,已经转行做抖音主播了,搞技术的只能赶在年前再水一篇博客,不足之处欢迎拍砖,以免误人子弟,呔,真是太难受了环境准备.ne......
  • cuda学习笔记5——CUDA实现图像形态学腐蚀、膨胀
    cuda学习笔记5——CUDA实现图像形态学腐蚀、膨胀​​代码​​​​linux如何编译cuda和opencv代码​​代码#include"cuda_runtime.h"#include"device_launch_parameters.h"......
  • 【学习笔记】分治
    分治相关的东西我基本都不会。CDQ分治最经典的分治,一般用于去掉一层偏序。对于一个区间\([l,r]\)的答案,我们可以找一个中点\(mid\),递归计算出\([l,mid]\)的答案......
  • 设计模式学习笔记
    静态工厂工厂方法可以隐藏创建产品的细节,且不一定每次都会真正创建产品,完全可以返回缓存的产品,从而提升速度并减少内存消耗。里氏替换原则返回实现接口的任意子类都可以......