Go.基础篇-1

  1 package main 
  2 
  3 import "fmt"
  4 import "math"
  5 import "errors"
  6 
  7 func main(){
  8     fmt.Println("Hello,World!")
  9     fmt.Println("Hello,Red!")    
 10 
 11     test_var()
 12     test_string()
 13     test_const()
 14     test_Iota()
 15     test_bit()
 16     test_for()
 17     test_swap()
 18     test_swapRef()
 19     test_sqrt()
 20     test_sequeue()
 21     test_select()
 22     test_type()
 23     test_struct()
 24     test_map()
 25     test_interface()
 26     test_error()
 27 }
 28 
 29 /*
 30 1.第一行代码 package main 定义了包名。你必须在源文件中非注释的第一行指明这个文件属于哪个包,
 31 如:package main。package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包
 32 2.fmt 包实现了格式化 IO(输入/输出)的函数
 33 3.当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头 相当于 public ;
 34 4.标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 private )
 35 */
 36 
 37 /*----------------------------------------------------
 38 Go 保留关键字 25 个 
 39 break default func interface select
 40 case defer go map struct
 41 chan else goto package switch
 42 const fallthrough if range type
 43 continue for import return var 
 44 
 45 # Go 语言还有 36 个预定义标识符
 46 append bool byte cap close complex complex64 complex128 uint16
 47 copy false float32 float64 imag int int8 int16 uint32
 48 int32 int64 iota len make new nil panic uint64
 49 print println real recover string true uint uint8 uintptr
 50 
 51 # Go 派生类
 52 指针类型 Pointer
 53 数组类型
 54 结构化类型 struct
 55 联合体类型 union
 56 函数类型
 57 切片类型
 58 接口类型 interface
 59 Map 类型
 60 Channel 类型
 61 
 62 # Go 数字类型
 63 uint8 无符号 8 位整型 (0 到 255)
 64 uint16 无符号 16 位整型 (0 到 65536)
 65 uint32 无符合 32 位整型 (0 到 4294967295)
 66 uint64 无符合 64 位整型 (0 到 18446744073709551615)
 67 int8 有符号 8 位整型 (-128 到 127)
 68 int16 有符号 16 位整型 (-32768 到 32767) 
 69 int32 有符号 32 位整型 (-2147483648 到 2147483647)
 70 int64 有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)
 71 
 72 # Go 浮点型
 73 float32 IEEE-754 32位浮点型数
 74 float64 IEEE-754 64位浮点型数
 75 complex64 32 位实数和虚数
 76 complex128 64 位实数和虚数
 77 
 78 # Go 其他数字类型
 79 byte 类似 uint8
 80 rune 类似 int32
 81 uint 32 或 64
 82 int 与 uint 一样大小
 83 uintptr 无符号整型,用于存放一个指针
 84 
 85 *-------------------------------------------------------
 86 */
 87 
 88 
 89 func test_var(){
 90     
 91     // 1.指定变量类型,声明后若不赋值,使用默认值。
 92     var a int    // a = 0
 93     // 2.缺省推导
 94     var b = 10  
 95     // 3.省略var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误,不能用在全局声明中
 96     c := a + b
 97 
 98     fmt.Println(a,b,c)
 99 
100     // 声明 同一类型多个变量
101     var d, e, f int
102 
103     fmt.Println(d,e,f)
104 
105     // 多变量同一行赋值
106     var g, h int
107     var i string
108     g, h, i = 5, 7, "abc"
109     
110     fmt.Println(g,h,i)
111 
112     // :=
113     j, k, l := 9, 10, "def"
114     fmt.Println(j,k,l)
115 
116     // 右边的这些值以相同的顺序赋值给左边的变量,
117     // 所以 a 的值是 5, b 的值是 7,c 的值是 "abc"。
118     // 这被称为 并行 或 同时 赋值。
119 
120     // 交互值
121     j, k = k, j
122     fmt.Println(j,k)
123 
124     // 空白标识符 _ 也被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃
125     // _ 实际上是一个只写变量,你不能得到它的值。这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值。
126     // 并行赋值也被用于当一个函数返回多个返回值时,比如这里的 val 和错误 err 是通过调用 Func1 函数同时得到:val, err = Func1(var1)。
127 }
128 
129 func test_string(){
130 
131     // 值类型:int,float,bool,string 这些基本类型都属于值类型,使用这些类型变量直接指向内存中的值
132     // 当使用 = 将一个变量赋值给另一个变量时,如:j = i ,实际是在内存中将 i 的值进行了拷贝
133     // (int) i -> 7
134     // (int) j -> 7
135     
136     i := 7
137     var j = i
138 
139     fmt.Println(i,j)
140 
141     // 通过 & 取内存地址
142     fmt.Println(&i)
143 }
144 
145 func test_const(){
146     // const identifier [type] = value
147 
148     // 显示定义
149     const a string = "abc"
150     // 隐式定义
151     const b = "def"
152     // 多个相同类型声明
153     const c, d = "cccc", "dddd"
154 
155 
156     fmt.Println(a,b,c,d)
157 
158     const LENGTH int = 10
159     const WIDTH int = 5
160 
161     var area int
162     area = LENGTH * WIDTH
163 
164     fmt.Printf("Area : %d", area)
165     fmt.Println()
166 
167     // Iota
168 }
169 
170 func test_Iota(){
171     // iota ,特殊常量,可以认为是一个可以被编译器修改的常量。
172     /*
173         在每一个const 关键字出现时,被重置为 0 , 在下一个const 出现之前,每出现一次iota
174         其所代表的数字会自动加 1 
175 
176     */
177 
178     const (
179         aa = iota
180         bb = iota
181         cc = iota
182     )
183 
184     fmt.Println(aa,bb,cc)
185 
186     const(
187         a = iota // 0
188         b         // 1
189         c         // 2    
190         d = "ha" // "ha" 独立值 iota += 1
191         e         // "ha" iota += 1
192         f = 100  // 100  iota += 1
193         g          // 100  iota += 1
194         h = iota // 7,恢复计数
195         i         // 8
196     )
197 
198     fmt.Println(a,b,c,e,f,g,h,i)
199 }
200 
201 func test_bit(){
202     // 位运算符对整数在内存中的二进制位进行操作
203     /* 位运算符 & | ^
204     p    q    p & q    p | q    p ^ q
205     0    0    0    0    0
206     0    1    0    1    1
207     1    1    1    1    0
208     1    0    0    1    1
209     
210 
211     A = 0011 1100
212     B = 0000 1101
213 
214     ------------------
215 
216     A & B = 0000 1100
217 
218     A | B = 0011 1101
219 
220     A ^ B = 0011 0001 // 相同为0 不相同为1  按位异或运算符"^"
221 
222     ~A = 1100 0011 // 每bit 倒序
223 
224     ---------------------
225     A << 2 左移 n 位就是乘以 2 的 n 次方 
226     A =     0011 1100 
227     A<<2 =  1111 0000    高位丢弃,低位补0
228 
229     A >> 2 右移 n 位就是除以 2 的 n 次方
230     A   =   0011 1100
231     A >>2   0000 1111 
232     */
233 
234     var a uint = 60 // 60 = 0011 1100
235     var b uint = 13 // 13 = 0000 1101
236     var c uint = 0
237 
238     c = a & b // 12 = 0000 1100
239     fmt.Printf("1. a & b = %d \n", c)
240 
241     c = a | b // 61 = 0000 1100
242     fmt.Printf("2. a | b = %d \n", c)
243 
244     c = a ^ b // 49 = 0011 0001 
245     fmt.Printf("3. a ^ b = %d \n", c)
246 
247     c = a << 2 // 240
248     fmt.Printf("4. a << 2 = %d \n", c)
249 
250     c = a >> 2 // 15
251     fmt.Printf("5. a >> 2 = %d \n", c)
252 
253     // & * ---------------------------
254     // & 返回变量存储地址
255     // * 指针变量
256 
257     var d int32 = 4
258     var ptr *int32
259 
260     ptr = &d 
261     fmt.Printf("d 的类型:%T \n",d)
262     fmt.Printf("*ptr 取值为 :%d\n",*ptr)
263 }
264 
265 func test_for(){
266 
267     // for init; condition; post { }
268     // for condition { }
269     // 和 C 的 for(;;) 一样: for { }
270     /* for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:
271         for key, value := range oldMap {
272             newMap[key] = value
273         }
274     */
275 
276     var b int = 15
277     var a int
278     numbers := [6]int {1, 2, 3, 5}
279 
280     for a:=0; a < 10; a++ {
281         fmt.Printf("a = %d \n", a)
282     }
283 
284     for a < b {
285         a++
286         fmt.Printf("a = %d \n", a)
287     }
288 
289     for i,x := range numbers {
290         fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
291     }
292 
293 }
294 
295 func test_swap(){
296     var a int = 100
297     var b int = 200
298 
299     fmt.Printf("交换前 a = %d\n", a)
300     fmt.Printf("交互前 b = %d\n", b)
301 
302     swap(a,b)
303 
304     fmt.Printf("交换后 a = %d\n", a)
305     fmt.Printf("交互后 b = %d\n", b)
306 }
307 
308 // 值传递
309 func swap(x,y int) int {
310     var temp int
311 
312     temp = x 
313     x = y
314     y = temp
315 
316     return temp
317 }
318 
319 func test_swapRef(){
320     var a int = 100
321     var b int = 200
322 
323     fmt.Printf("交换前 a = %d\n", a)
324     fmt.Printf("交换前 b = %d\n", b)
325 
326     swapRef(&a,&b)
327 
328     fmt.Printf("交换后 a = %d\n", a)
329     fmt.Printf("交换后 b = %d\n", b)
330 }
331 
332 func swapRef(x *int, y *int) {
333     var temp int
334 
335     temp = *x
336     *x = *y
337     *y = temp
338 }
339 
340 func test_sqrt(){
341     // Go 语言可以很灵活的创建函数,并作为值使用
342 
343     getSquare := func(x float64) float64 {
344         return math.Sqrt(x)
345     }
346 
347     fmt.Println(getSquare(25))
348     println()
349 }
350 
351 // 匿名函数和闭包
352 // Go 语言支持匿名函数,可作为闭包。匿名函数是一个"内联"语句或表达式。
353 // 匿名函数的优越性在于可以直接使用函数内的变量,不必申明。
354 func test_sequeue(){
355 
356     // nextNumber 为一个函数,函数 i 为 0
357     nextNumber := getSequeue()
358 
359     fmt.Println(nextNumber())
360     fmt.Println(nextNumber())
361     fmt.Println(nextNumber())
362     println()
363 
364     next2 := getSequeue()
365 
366     fmt.Println(next2())
367     fmt.Println(next2())
368     fmt.Println(next2())
369     fmt.Println(next2())
370     fmt.Println(next2())
371     println()
372 
373     fmt.Println(nextNumber())
374 }
375 
376 func println(){
377     fmt.Println("------------------------");
378 }
379 
380 func getSequeue() func() int {
381     i := 0
382 
383     return func() int {
384         i += 1
385         return i
386     }
387 }
388 
389 /*
390 * select 是 Go 中一个控制结构,类似于用于通信的 switch 语句。
391 * 每个case 必须是一个通信操作,要么发送,要么接收。
392 
393 select {
394     case communication clause  :
395        statement(s);      
396     case communication clause  :
397        statement(s); 
398     你可以定义任意数量的 case 
399     default : 
400     statement(s);
401 }
402 
403 每个case都必须是一个通信
404 所有channel表达式都会被求值
405 所有被发送的表达式都会被求值
406 如果任意某个通信可以进行,它就执行;其他被忽略。
407 如果有多个case都可以运行,Select会随机公平地选出一个执行。其他不会执行。 
408 否则:
409 如果有default子句,则执行该语句。
410 如果没有default字句,select将阻塞,直到某个通信可以运行;
411 Go不会重新对channel或值进行求值。
412 
413 */
414 func test_select(){
415 
416     var c1,c2,c3 chan int
417     var b1,b2,b3 int
418 
419     select {
420 
421         case c1 <- b1: // to do ?? <-
422             fmt.Println("c1")
423         case c2 <- b2:
424             fmt.Println("c2")
425         case c3 <- b3:
426             fmt.Println("c3")
427     
428         default:
429             fmt.Println("no communication")
430     }
431 
432     println()
433 }
434 
435 func test_type(){
436     // 类型转换 type_name(expression) 
437     var sum int = 17
438     var count int = 5
439     var mean float32
440 
441     mean = float32(sum)/float32(count)
442 
443     fmt.Printf("mean = %f\n", mean)
444     println()
445 }
446 
447 func test_ptr(){
448     /*
449       Go 语言
450     */
451 }
452 
453 func test_struct(){
454     /* 
455     结构体是由一系列具有相同类型或不同类型的数据构成的数据集合
456     
457     type struct_variable_type struct {
458         member definition;
459         member definition;
460         ...
461         member definition;
462     }
463 
464     variable_name := structure_variable_type {value1, value2...valuen}
465 
466     */
467 
468     var book1 Books
469     var book2 Books
470 
471     book1.title = "Go 语言"
472     book1.author = "www.w3cschool.com"
473     book1.subject = "Go 语言教程"
474     book1.id = 6495407
475 
476     book2.title = "Python 教程"
477     book2.author = "www.w3cschool.cn"
478     book2.subject = "Python 语言教程"
479     book2.id = 6495700
480 
481     fmt.Println("book1:", book1)
482     fmt.Printf("book 1 title : %s\n", book1.title)
483     fmt.Printf("book 1 author : %s\n", book1.author)
484     fmt.Printf("book 1 subjiect : %s\n", book1.subject)
485 
486     println()
487     fmt.Printf("book 2 title : %s\n", book2.title)
488     fmt.Printf("book 2 author : %s\n", book2.author)
489     fmt.Printf("book 2 subjiect : %s\n", book2.subject)
490 
491     println()
492 
493     printBook(book1)
494     printBook(book1)
495     
496     printBookRef(&book2)
497     printBookRef(&book2)
498 }
499 
500 func printBook(book Books){
501     book.title = "ddddd"
502     fmt.Printf("book title : %s\n", book.title)
503     fmt.Printf("book author : %s\n", book.author)
504     fmt.Printf("book subjiect : %s\n", book.subject)
505     book.title = "eeeee"
506     println()
507 }
508 
509 func printBookRef(book *Books){
510     book.title = "ddddd"
511     fmt.Printf("book title : %s\n", book.title)
512     fmt.Printf("book author : %s\n", book.author)
513     fmt.Printf("book subjiect : %s\n", book.subject)
514     book.title = "eeeee"
515     println()
516 
517     test_range()
518 }
519 
520 type Books struct {
521     title string
522     author string
523     subject string
524     id int
525 }
526 
527 // Range 关键字用于for 循环中迭代数组 array,切片 slice ,链表 channel 或集合 map 的元素
528 // 在数组和切片中它返回元素的索引值,在集合中返回 key-value 对的 key 值
529 func test_range(){
530     
531     nums := []int { 2, 3, 4}
532     sum := 0
533 
534     for _,x := range nums {
535         sum += x
536     }
537 
538     fmt.Println("sum:", sum)
539 
540     // 在数组中使用range 将传入 index 和 值两个变量。
541 
542     for i,num := range nums {
543         fmt.Printf("i:%d,num:%d\n", i, num)
544     }
545 
546     // range 也可以用在map 的键值对上
547     kvs := map[string]string { "a" : "apple", "b" : "banana"}
548 
549     for k,v := range kvs {
550         fmt.Printf("%s -> %s \n",k,v)
551     }
552 
553     // range 用来枚举 unicode 字符串,第一个是字符的索引,第二个字符(unicode 的值) 本身
554     for i,c := range "golang" {
555         fmt.Println(i,c)
556     }
557 
558     println()
559     test_slice()
560 }
561 
562 // slice Go 语言切片是对数组的抽象
563 // Go 语言数组长度不可变,在特定场景中这样的集合就不太适用,Go中提供一种灵活,功能强悍的内置类型切片
564 // (动态数组),与数组相比长度是不固定的,可以追加元素,在追加是可能使切片的容量增大
565 // 定义切片
566 /* 
567     var identifier []type
568     切片不需要说明长度
569     或者使用 make() 函数来创建切片:
570     var slice1 []type = make([]type,len)
571     简写:
572     slice1 := make([]type,len)
573     指定容量:
574     make([]T,length,capacity)
575     切片初始化:
576     s := [] int {1, 2, 3}
577     直接初始化切片, [] 表示切片类型 , {1,2,3} 初始化值依次是1,2,3,其 cap = len =3
578 
579     s := arr[:] // 初始化切片 s 是数组 arr 的引用
580 
581     s := arr[startIndex:endIndex] // 将arr中下标 startIndex 到 endIndex -1 下的元素创建为一个新的切片
582 
583     s := arr[:endIndex] 从下标 0 - endIndex-1
584 
585     s := arr[startIndex:] 从 startIndex 到结尾
586 
587 
588 */
589 
590 func test_slice(){
591     var num = make([]int, 3, 5)
592     printSlice(num)
593     
594 
595     x := []int {0,1,2,3,4,5,6,7,8}
596     printSlice(x)
597 
598     // 打印切片索引从 1 (包含),到 4 (不包含)
599     fmt.Println("x[1:4] == ", x[1:4])
600 
601     // 切片默认下限 为 0
602     fmt.Println("x[:3] == ", x[:3])
603 
604     // 切片默认上限为 len(x) 
605     fmt.Println("x[4:] == ", x[4:])
606 
607     y := make([]int,0,5)
608     printSlice(y)
609 
610     x1 := x[:2]
611     printSlice(x1)
612 
613     x2 := x[2:5]
614     printSlice(x2)
615 
616     println()
617     test_copyappend()
618 }
619 
620 func test_copyappend(){
621     // 如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容拷贝过来
622     // append(),copy() 函数    
623 
624     var x []int
625     printSlice(x)
626 
627     // 允许追加空切片
628     x = append(x, 0)
629     printSlice(x)
630 
631     // 追加一个元素
632     x = append(x, 1)
633     printSlice(x)
634 
635     // 同事添加多个元素
636     x = append(x, 2, 3, 4)
637     printSlice(x)
638 
639     // 创建切片 是 x 容量的 2 倍
640     x1 := make([]int, len(x), (cap(x))*2)
641     printSlice(x1)
642 
643     // copy x 到 x1
644     copy(x1,x)
645     printSlice(x1)
646     println()
647 }
648 
649 func printSlice(x []int){
650     fmt.Printf("len=%d cap=%d slice=%v\n",len(x), cap(x), x)
651 }
652 
653 /*
654 Go 语言 Map (集合)
655 Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据, key 类似于索引,
656 指向数据的值。
657 Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,因为
658 Map 是使用 hash 表来实现的。
659 
660 定义 Map 
661 默认是 nil 
662 var map_variable map[key_data_type]value_data_type
663 
664 make 函数
665 map_variable = make(map[key_data_type]value_data_type)
666 
667 未初始化的 map 是一个 nil map, 不能用来存放数据
668 
669 */
670 
671 func test_map(){
672     // nil
673     var m map[string]string
674     fmt.Println(m)
675 
676     // 初始化
677     m = make(map[string]string)
678 
679     // map 插入 key-value 对
680     m["France"] = "Paris"
681     m["Italy"] = "Rome"
682     m["Japan"] = "Tokyo"
683     m["India"] = "New Delhi"
684 
685     // 使用 key 遍历 map
686     for key := range m {
687         fmt.Println("Capital of",key,"is",m[key])
688     }
689 
690     // 查看元素是否存在
691     capital, ok := m["United States"]
692 
693     if(ok) {
694         fmt.Println("Capital of United States is", capital)
695     }else {
696         fmt.Println("Capital of United States is not present")
697     }
698 
699     // 删除元素
700     delete(m,"France")
701     fmt.Println("France is deleted")
702 
703     for key := range m {
704         fmt.Println("Capital of",key,"is",m[key])
705     }
706 
707     println()
708 
709     test_fac()
710 }
711 
712 // Go 语言递归
713 // 递归就是运行过程中调用自己
714 // Go 语言支持递归, 但我们在使用递归时,需要设置退出条件,否则将陷入无限循环中
715 func test_fac() {
716 
717     var i int = 15
718     fmt.Printf("%d 的阶乘 = %d\n", i ,factorial(i))
719 
720     // 斐波那契数列
721     for j:=0; j < 10; j++ {
722         fmt.Printf("%d\t",fibonaci(j))
723     }
724 
725     fmt.Println()
726 
727     println()
728 
729 }
730 
731 func fibonaci(n int) int {
732     if n < 2 {
733         return n
734     }
735 
736     return fibonaci(n-2) + fibonaci(n-1)
737 }
738 
739 func factorial(x int) (result int) {
740     if x == 0 {
741         result = 1
742     } else {
743         result = x * factorial(x - 1)
744     }
745 
746     return;
747 }
748 
749 /*
750 Go 语言提供另外一种数据类型即接口,它把所有具有共性的方法定义在一起,
751 任何其他类型只要实现了这些方法就是实现了这个接口
752 
753 定义:
754 type interface_name interface {
755     method_name1 [return_type]
756     method_name2 [return_type]
757     method_name3 [return_type]
758     ...
759 }
760 
761 定义结构体:
762 type struct_name struct {
763     // variables
764 }
765 
766 实现接口方法
767 func (struct_name_variable struct_name) method_name1() [return_type] {
768     // 实现方法
769 }
770 
771 */
772 
773 type Phone interface {
774     call()
775 }
776 
777 type NokiaPhone struct {
778 
779 }
780 
781 func (nokia NokiaPhone) call() {
782     fmt.Println("I am Nokia, I can call you.")
783 }
784 
785 type IPhone struct {
786 
787 }
788 
789 func (iphone IPhone) call() {
790     fmt.Println("I am IPhone, I can call you.")
791 }
792 
793 func test_interface() {
794     var phone Phone
795 
796     phone = new(NokiaPhone)
797     phone.call()
798 
799     phone = new(IPhone)
800     phone.call()
801 
802     println()
803 }
804 
805 /*
806 Go 语言通过内置的错误接口提供了非常简单的错误处理机制
807 error 类型是一个接口类型,定义:
808 
809 type error interface {
810     Error() string
811 }
812 
813 我们可以在编码中通过实现 error 接口类型来生成错误信息
814 函数通常在最后的返回值中返回错误信息. 使用 errors.New 可返回一个错误信息
815 
816 */
817 
818 func test_error() {
819     
820     //_,err := Sqrt(4)
821     _,err := Sqrt(-1)
822 
823     if err != nil {
824         fmt.Println(err)
825     }
826 }
827 
828 func Sqrt(f float64) (float64,error) {
829 
830     if f < 0 {
831         return 0, errors.New("math:square root of negative number")
832     }
833 
834     return math.Sqrt(f),nil
835 }

------------------------------------------------------------------------------------

1.参考

https://www.w3cschool.cn/go/

转载于:https://www.cnblogs.com/welanshan/p/7800676.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值