Go入门(四)之工程管理、复合类型

上一篇文章> Go入门(三)之自定义函数、匿名函数、闭包、defer、作用域

一、工程管理


1、工作区

(1)工作区介绍

在这里插入图片描述

(2)GOPATH设置

在这里插入图片描述

2、包

同一目录导入,package 包名相同
不同目录导入,package 包名不同,且函数必须首字母大写才能调用

import io "fmt"     //起别名,fmt为io
import _ "fmt"     //忽略,调用该包里面的init函数

二、复合类型


1、指针

(1)指针的基本操作
package main

import "fmt"

func main() {
	var a int = 10
	// 每个变量有2层含义: 变量的内存,变量的地址
	fmt.Printf("a = %d\n", a) //变量的内存
	fmt.Printf("&a = %v\n", &a)

	// 保存某个变量的地址,需要指针类型  *int 保存int的地址, **int保存*int地址
	//声明(定义), 定义只是特殊的声明
	// 定义一个变量p,类型为*int
	var p *int
	p = &a //指针变量指向谁,就把谁的地址赋值给指针变量
	fmt.Printf("p = %v, &a = %v\n", p, &a)

	*p = 666 //*p操作的不是p的内存,是p所指向的内存即a
	fmt.Printf("*p = %v, a = %v\n", *p, a)
}

结果:

a = 10
&a = 0xc0000120a0
p = 0xc0000120a0, &a = 0xc0000120a0
*p = 666, a = 666
(2)new

内存会自动回收

package main

import "fmt"

func main() {
	var p *int

	// p是*int,指向int类型
	p = new(int)
	*p = 666
	fmt.Println("*p = ", *p)

	q := new(int) // 自动推导类型
	*q = 777
	fmt.Println("*q = ", *q)
}

结果:

*p =  666
*q =  777
(3)值传递
package main

import "fmt"

func swap(a, b int) {
	a, b = b, a
	fmt.Printf("swap: a = %d, b = %d\n", a, b)
}

func main() {
	a, b := 10, 20
	swap(a, b) // 变量本身传递
	fmt.Printf("main: a = %d, b = %d\n", a, b)
}

结果:

swap: a = 20, b = 10
main: a = 10, b = 20
(4)指针做函数参数
package main

import "fmt"

func swapP(p1, p2 *int) {
	*p1, *p2 = *p2, *p1
}

func main() {
	a, b := 10, 20
	swapP(&a, &b) // 变量本身传递
	fmt.Printf("main: a = %d, b = %d\n", a, b)
}

结果:

main: a = 20, b = 10

2、数组

(1)数组初体验

数组个数必须是常量

package main

import "fmt"

func main() {
	var id [5]int

	for i := 0; i < len(id); i++ {
		id[i] = i + 1
		fmt.Printf("id[%d] = %d\n", i, id[i])
	}
}

结果:

id[0] = 1
id[1] = 2
id[2] = 3
id[3] = 4
id[4] = 5
(2)数组的基本使用
package main

import "fmt"

func main() {
	var a [5]int

	a[0] = 1
	i := 1
	a[i] = 2 //a[1] = 2
	fmt.Println("a = ", a)

	for i := 0; i < len(a); i++ {
		a[i] = i + 1
	}
	for i, data := range a {
		fmt.Printf("a[%d] = %d\n", i, data)
	}
}

结果:

a =  [1 2 0 0 0]
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
a[4] = 5
(3)数组初始化
package main

import "fmt"

func main() {
	// 1、全部初始化
	var a [5]int = [5]int{1, 2, 3, 4, 5}
	fmt.Println("a = ", a)

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

	// 2、部分初始化
	c := [5]int{1, 2, 3}
	fmt.Println("c = ", c)

	// 3、制定某个元素初始化
	d := [5]int{2: 10, 4: 20}
	fmt.Println("d = ", d)
}

结果:

a =  [1 2 3 4 5]
b =  [1 2 3 4 5]
c =  [1 2 3 0 0]
d =  [0 0 10 0 20]
(4)二维数组
package main

import "fmt"

func main() {
	// 有多少个[]就是多少维
	// 有多少个[]就用多少个循环
	var a [3][4]int
	k := 0
	for i := 0; i < 3; i++ {
		for j := 0; j < 4; j++ {
			k++
			a[i][j] = k
			fmt.Printf("a[%d][%d]= %d, ", i, j, a[i][j])
		}
		fmt.Printf("\n")
	}

	fmt.Println("a = ", a)

	b := [3][4]int{{1, 2, 3, 4}, {5, 7, 8}}
	fmt.Println("b = ", b)

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

结果:

a[0][0]= 1, a[0][1]= 2, a[0][2]= 3, a[0][3]= 4,
a[1][0]= 5, a[1][1]= 6, a[1][2]= 7, a[1][3]= 8,
a[2][0]= 9, a[2][1]= 10, a[2][2]= 11, a[2][3]= 12,
a =  [[1 2 3 4] [5 6 7 8] [9 10 11 12]]
b =  [[1 2 3 4] [5 7 8 0] [0 0 0 0]]
c =  [[0 0 0 0] [1 2 3 4] [0 0 0 0]]
(5)数组比较和赋值
package main

import "fmt"

func main() {
	// 支持比较,只支持 == 或 !=
	a := [5]int{1, 2, 3, 4, 5}
	b := [5]int{1, 2, 3, 4, 5}
	c := [5]int{1, 2, 3}
	fmt.Println("a == b", a == b)
	fmt.Println("a == c", a == c)

	// 同类型的数组可以赋值
	var d [5]int
	d = a
	fmt.Println("d = ", d)
}

结果:

a == b true
a == c false
d =  [1 2 3 4 5]
(6)随机数的使用
package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	// 设置种子,只需要一次
	// 如果种子参数一样,每次运行程序产生的随机数都一样
	// rand.Seed(666)

	rand.Seed(time.Now().UnixNano()) //以当前时间为种子参数

	for i := 0; i < 5; i++ {
		// 产生随机数
		fmt.Println("rand.Int = ", rand.Int())      //数会很大
		fmt.Println("rand.Intn = ", rand.Intn(100)) //限制在100以内
	}
}

结果:

rand.Int =  2185808407492445800
rand.Intn =  98
rand.Int =  4415649623385332937
rand.Intn =  6
rand.Int =  4014809768838185153
rand.Intn =  85
rand.Int =  3306828027594439067
rand.Intn =  74
rand.Int =  7867276672125053313
rand.Intn =  91
(7)冒泡排序
package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	rand.Seed(time.Now().UnixNano())

	var a [10]int
	n := len(a)
	for i := 0; i < n; i++ {
		a[i] = rand.Intn(100)
	}
	fmt.Println("a = ", a)

	for i := 0; i < n-1; i++ {
		for j := 0; j < n-1-i; j++ {
			if a[j] > a[j+1] {
				a[j], a[j+1] = a[j+1], a[j]
			}
		}
	}
	fmt.Println("排序后a = ", a)
}

结果:

a =  [23 29 87 84 82 67 95 59 39 14]
排序后a =  [14 23 29 39 59 67 82 84 87 95]
(8)数组做函数参数
package main

import "fmt"

// 数组做函数参数,它是值传递
func modify(a [5]int) {
	a[0] = 666
	fmt.Println("modify: a = ", a)
}

func main() {
	a := [5]int{1, 2, 3, 4, 5}
	modify(a)
	fmt.Println("main: a = ", a)
}

结果:

modify: a =  [666 2 3 4 5]
main: a =  [1 2 3 4 5]
(9)数组指针做函数参数
package main

import "fmt"

// 数组做函数参数,它是值传递
func modify(p *[5]int) {
	(*p)[0] = 666
	fmt.Println("modify: *a = ", *p)
}

func main() {
	a := [5]int{1, 2, 3, 4, 5}
	modify(&a) //地址传递
	fmt.Println("main: a = ", a)
}

结果:

modify: *a =  [666 2 3 4 5]
main: a =  [666 2 3 4 5]

3、slice

(1)切片的长度和容量

长度和容量:

array := [...]int{10, 20, 30, 0, 0}
slice := array[0:3:5]
[low:high:max]
low::下标得七点
high:下标得重点(不包括此下标),a[a[low], a[high])左闭右开
      len = high - low(长度)
cap = max - low(容量)
package main

import "fmt"

func main() {
	a := []int{1, 2, 3, 4, 5}
	s := a[0:3:5]
	fmt.Println("s = ", s)
	fmt.Println("len(s) = ", len(s))
	fmt.Println("cap(s) = ", cap(s))

	fmt.Println("-----------")
	s = a[1:4:5]
	fmt.Println("s = ", s)
	fmt.Println("len(s) = ", len(s))
	fmt.Println("cap(s) = ", cap(s))
}

结果:

s =  [1 2 3]
len(s) =  3 
cap(s) =  5 
----------- 
s =  [2 3 4]
len(s) =  3
cap(s) =  4
(2)切片和数组区别
package main

import "fmt"

func main() {
	// 切换和数组得区别

	// 1、数组[]里面得长度是常量
	a := [5]int{}
	fmt.Printf("len = %d, cap = %d\n", len(a), cap(a))

	// 2、切片, []里面为空,或者为...,切片得长度和容量可以不固定
	s := []int{}
	fmt.Printf("slice len = %d, cap = %d\n", len(s), cap(s))

	s = append(s, 11) //末尾添加
	fmt.Printf("append: len = %d, cap = %d\n", len(s), cap(s))
}

结果:

len = 5, cap = 5
slice len = 0, cap = 0
append: len = 1, cap = 1
(3)切换创建
package main

import "fmt"

func main() {
	// 自动推导类型
	s1 := []int{1, 2, 3, 4}
	fmt.Println("s1 = ", s1)

	// 借助make函数,格式make(slice, len, cap)
	s2 := make([]int, 5, 10)
	fmt.Printf("len = %d, cap = %d\n", len(s2), cap(s2))

	// 没有指定容量,容量和长度一样
	s3 := make([]int, 5)
	fmt.Printf("len = %d, cap = %d\n", len(s3), cap(s3))
}

结果:

s1 =  [1 2 3 4]
len = 5, cap = 10
len = 5, cap = 5
(4)切片截取

在这里插入图片描述

package main

import "fmt"

func main() {
	array := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	// [low:high:max] 去下标从low开始得元素,len=high-low,cap=max-low
	s1 := array[:] //[0:len(array):len(array)]
	fmt.Println("s1 = ", s1)
	fmt.Printf("len = %d, cap = %d\n", len(s1), cap(s1))

	// 操作某个元素,和数组操作方式一样
	data := array[1]
	fmt.Println("data = ", data)

	s2 := array[3:6:7]
	fmt.Println("s2 = ", s2)
	fmt.Printf("len = %d, cap = %d\n", len(s2), cap(s2))

	s3 := array[:6] //从0开始取6个元素,容量也是6
	fmt.Println("s3 = ", s3)
	fmt.Printf("len = %d, cap = %d\n", len(s3), cap(s3))

	s4 := array[3:] //从3开始到结尾
	fmt.Println("s4 = ", s4)
	fmt.Printf("len = %d, cap = %d\n", len(s4), cap(s4))
}

结果:

s1 =  [0 1 2 3 4 5 6 7 8 9]
len = 10, cap = 10
data =  1
s2 =  [3 4 5]
len = 3, cap = 4
s3 =  [0 1 2 3 4 5]
len = 6, cap = 10
s4 =  [3 4 5 6 7 8 9]
len = 7, cap = 7
(5)切片和底层数组关系
package main

import "fmt"

func main() {
	a := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

	// 新切片
	s1 := a[2:5] //从a[2]开始,取3个元素
	s1[1] = 666
	fmt.Println("s1 = ", s1)
	fmt.Println("a = ", a)

	//新切片
	s2 := s1[2:7]
	s2[2] = 777
	fmt.Println("s2 = ", s2)
	fmt.Println("a = ", a)
}

结果:

s1 =  [2 666 4]
a =  [0 1 2 666 4 5 6 7 8 9]
s2 =  [4 5 777 7 8]
a =  [0 1 2 666 4 5 777 7 8 9]
(6)append函数

<1> append函数的使用

package main

import "fmt"

func main() {
	s1 := []int{}
	fmt.Printf("len = %d, cap = %d\n", len(s1), cap(s1))
	fmt.Println("s1 = ", s1)

	// 在原切片的末尾添加元素
	s1 = append(s1, 1)
	s1 = append(s1, 2)
	s1 = append(s1, 3)
	fmt.Printf("len = %d, cap = %d\n", len(s1), cap(s1))
	fmt.Println("s1 = ", s1)

	s2 := []int{1, 2, 3}
	fmt.Println("s2 = ", s2)
	s2 = append(s2, 5)
	s2 = append(s2, 5)
	s2 = append(s2, 5)
	fmt.Println("s2 = ", s2)
}

结果:

len = 0, cap = 0
s1 =  []
len = 3, cap = 4   
s1 =  [1 2 3]      
s2 =  [1 2 3]      
s2 =  [1 2 3 5 5 5]

<2> append扩容特点

package main

import "fmt"

func main() {
	// 如果超过原来的容量,通常以2倍容量扩容
	s := make([]int, 0, 1) //容量为1
	oldCap := cap(s)
	for i := 0; i < 8; i++ {
		s = append(s, i)
		if newCap := cap(s); oldCap < newCap {
			fmt.Printf("cap: %d ==> %d\n", oldCap, newCap)
			oldCap = newCap
		}
	}
}

结果:

cap: 1 ==> 2
cap: 2 ==> 4
cap: 4 ==> 8
(7)copy的使用
package main

import "fmt"

func main() {
	srcSlice := []int{1, 2}
	dstSlice := []int{6, 6, 6, 6, 6}

	copy(dstSlice, srcSlice)
	fmt.Println("dst = ", dstSlice)
}

结果:

dst =  [1 2 6 6 6]
(8)切片做函数参数
package main

import "fmt"

func BubblerSort(s []int) {
	n := len(s)
	for i := 0; i < n-1; i++ {
		for j := 0; j < n-1-i; j++ {
			if s[j] > s[j+1] {
				s[j], s[j+1] = s[j+1], s[j]
			}
		}
	}
}

func main() {
	s := []int{8, 20, 3, 5, 7}
	BubblerSort(s)
	fmt.Println("s = ", s)
}

结果:

s =  [3 5 7 8 20]
(9)猜数字游戏
package main

import (
	"fmt"
	"math/rand"
	"time"
)

func CreatNum(p *int) {
	rand.Seed(time.Now().UnixNano())

	var num int
	for {
		num = rand.Intn(10000)
		if num >= 1000 {
			break
		}
	}

	*p = num
}

func GetNum(s []int, num int) {
	s[0] = num / 1000
	s[1] = num % 1000 / 100
	s[2] = num % 100 / 10
	s[3] = num % 10
}

func OnGame(randSlice []int) {
	var num int
	keySlice := make([]int, 4)
	for {
		for {
			fmt.Printf("请输入一个四位数:")
			fmt.Scan(&num)

			if 999 < num && num < 10000 {
				break
			}
			fmt.Printf("你输入的数不符合要求\n")
		}

		GetNum(keySlice, num)
		fmt.Println("keySlice = ", keySlice)

		n := 0
		for i := 0; i < 4; i++ {
			if keySlice[i] > randSlice[i] {
				fmt.Printf("第%d位大了一点\n", i+1)
			} else if keySlice[i] < randSlice[i] {
				fmt.Printf("第%d位小了一点\n", i+1)
			} else {
				fmt.Printf("第%d位猜对了\n", i+1)
				n++
			}
		}
		if n == 4 {
			fmt.Printf("全部猜对")
			break
		}
	}

}

func main() {
	var randNum int
	// 生成随机四位数
	CreatNum(&randNum)
	fmt.Println("randNum = ", randNum)

	randSlice := make([]int, 4)
	// 保存4位数的每一位
	GetNum(randSlice, randNum)
	fmt.Println("s = ", randSlice)

	OnGame(randSlice)
}

4、map

map(映射、字典)是一种内置的数据结构,它是一种无序的key-value对的集合且是无序的
map格式为:map[keyType]valueType

(1)map的基本使用
package main

import "fmt"

func main() {
	var m1 map[int]string
	fmt.Println("m1 = ", m1)

	// 对于map只有len,没有cap
	fmt.Println("len = ", len(m1))

	// 可以用过make创建
	m2 := make(map[int]string)
	fmt.Println("m2 = ", m2)
	fmt.Println("len = ", len(m2))

	// 可以通过make创建,可以指定长度
	m3 := make(map[int]string, 10)
	m3[1] = "wielun"
	fmt.Println("m3 = ", m3)
	fmt.Println("len = ", len(m3))

	//初始化
	m4 := map[int]string{1: "mike", 2: "go"}
	fmt.Println("m4 = ", m4)
}

结果:

m1 =  map[]
len =  0
m2 =  map[]
len =  0
m3 =  map[1:wielun]
len =  1
m4 =  map[1:mike 2:go]
(2)map赋值
package main

import "fmt"

func main() {
	m1 := map[int]string{1: "wielun", 2: "go"}
	fmt.Println("m1 = ", m1)
	m1[2] = "hello go"
	fmt.Println("m1 = ", m1)
	m1[3] = "hello wielun"
	fmt.Println("m1 = ", m1)
}

结果:

m1 =  map[1:wielun 2:go]
m1 =  map[1:wielun 2:hello go]
m1 =  map[1:wielun 2:hello go 3:hello wielun]
(3)map遍历
package main

import "fmt"

func main() {
	m := map[int]string{1: "wielun", 2: "hello wielun", 3: "hello world"}

	// 遍历的结果是无序的
	for key, value := range m {
		fmt.Printf("%d ==> %s\n", key, value)
	}

	// 判断key值是否存在
	// ok为key是否存在的条件
	value, ok := m[0]
	if ok == true {
		fmt.Println("m[1] = ", value)
	} else {
		fmt.Printf("key不存在")
	}
}

结果:

1 ==> wielun
2 ==> hello wielun
3 ==> hello world
key不存在
(4)map删除
package main

import "fmt"

func main() {
	m := map[int]string{1: "wielun", 2: "hello wielun", 3: "hello world"}
	delete(m, 1) //删除key为1的内容
	fmt.Println("m = ", m)
}

结果:

m =  map[2:hello wielun 3:hello world]
(5)map做函数参数
package main

import "fmt"

func test(m map[int]string) {
	delete(m, 1)
}

func main() {
	m := map[int]string{1: "wielun", 2: "hello wielun", 3: "hello world"}
	test(m)
	fmt.Println("m = ", m)
}

结果:

m =  map[2:hello wielun 3:hello world]

5、结构体

如果想使用别的包的函数、结构体类型、结构体成员
函数名,类型名,结构体成员变量名,首字母必须大写

(1)结构体普通变量初始化
package main

import "fmt"

// 定义一个结构体类型
type Student struct {
	id   int
	name string
	sex  byte // 字符类型
	age  int
	addr string
}

func main() {
	// 顺序初始化,每个成员必须初始化
	var s1 Student = Student{1, "mike", 'm', 18, "bj"}
	fmt.Println("s1 = ", s1)

	// 制定成员初始化,没有初始化的成员,自动赋值为0
	s2 := Student{name: "mike", addr: "bj"}
	fmt.Println("s2 = ", s2)
}

结果:

s1 =  {1 mike 109 18 bj}
s2 =  {0 mike 0 0 bj}
(2)结构体指针变量初始化
package main

import "fmt"

// 定义一个结构体类型
type Student struct {
	id   int
	name string
	sex  byte // 字符类型
	age  int
	addr string
}

func main() {
	// 顺序初始化,每个成员必须初始化
	var p1 *Student = &Student{1, "mike", 'm', 18, "bj"}
	fmt.Println("*p1 = ", *p1)
	fmt.Println("p1 = ", p1)

	// 制定成员初始化,没有初始化的成员,自动赋值为0
	p2 := &Student{name: "mike", addr: "bj"}
	fmt.Println("*p2 = ", *p2)
	fmt.Println("p2 = ", p2)
}

结果:

*p1 =  {1 mike 109 18 bj}
p1 =  &{1 mike 109 18 bj}
*p2 =  {0 mike 0 0 bj}
p2 =  &{0 mike 0 0 bj}
(3)结构体成员的使用(普通变量)
package main

import "fmt"

// 定义一个结构体类型
type Student struct {
	id   int
	name string
	sex  byte // 字符类型
	age  int
	addr string
}

func main() {
	var s Student

	// 操作成员,需要使用(.)运算符
	s.id = 1
	s.name = "wielun"
	s.sex = 'm'
	s.age = 18
	s.addr = "bj"
	fmt.Println("s = ", s)
}

结果:

s =  {1 wielun 109 18 bj}
(4)结构体成员的使用(指针变量)
package main

import "fmt"

// 定义一个结构体类型
type Student struct {
	id   int
	name string
	sex  byte // 字符类型
	age  int
	addr string
}

func main() {
	// 1、指针有合法指向后,才操作成员
	// 先定义一个普通结构体变量
	var s Student
	// 在定义一个指针变量,保存s的地址
	var p1 *Student
	p1 = &s

	// 通过指针操作成员 p1.id和(*p1).id完全等价,只能使用.运算符
	p1.id = 18
	(*p1).name = "mike"
	p1.sex = 'm'
	p1.age = 18
	p1.addr = "bj"
	fmt.Println("p1 = ", p1)

	// 2、通过new申请一个结构体
	p2 := new(Student)
	p2.id = 18
	p2.name = "mike"
	p2.sex = 'm'
	p2.age = 18
	p2.addr = "bj"
	fmt.Println("p2 = ", p2)
}

结果:

p1 =  &{18 mike 109 18 bj}
p2 =  &{18 mike 109 18 bj}
(5)结构体比较和赋值
package main

import "fmt"

// 定义一个结构体类型
type Student struct {
	id   int
	name string
	sex  byte // 字符类型
	age  int
	addr string
}

func main() {
	s1 := Student{1, "mike", 'm', 18, "bj"}
	s2 := Student{1, "mike", 'm', 18, "bj"}
	s3 := Student{2, "mike", 'm', 18, "bj"}
	fmt.Println("s1 == s2", s1 == s2)
	fmt.Println("s1 == s3", s1 == s3)

	// 同类型的2个结构体变量可以互相赋值
	var tmp Student
	tmp = s3
	fmt.Println("tmp = ", tmp)
}

结果:

s1 == s2 true
s1 == s3 false
tmp =  {2 mike 109 18 bj}
(6)结构体作为函数参数(值传递)
package main

import "fmt"

// 定义一个结构体类型
type Student struct {
	id   int
	name string
	sex  byte // 字符类型
	age  int
	addr string
}

func test01(s Student) {
	s.id = 666
	fmt.Println("test01: ", s)
}

func main() {
	s := Student{1, "mike", 'm', 18, "bj"}

	test01(s) //值传递,形参无法改实参
	fmt.Println("main: ", s)
}

结果:

test01:  {666 mike 109 18 bj}
main:  {1 mike 109 18 bj}
(7)结构体作为函数参数(地址传递)
package main

import "fmt"

// 定义一个结构体类型
type Student struct {
	id   int
	name string
	sex  byte // 字符类型
	age  int
	addr string
}

func test02(p *Student) {
	p.id = 666
	fmt.Println("test01: ", p)
}

func main() {
	s := Student{1, "mike", 'm', 18, "bj"}

	test02(&s) //地址传递,形参可以传递
	fmt.Println("main: ", s)
}

结果:

test01:  &{666 mike 109 18 bj}
main:  {666 mike 109 18 bj}

下一篇文章> Go入门(五)之面向对象编程、异常处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wielun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值