Advanced Go Features(Reflection | unsafe code)

Reflection allows you to dynamically learn the type of an arbitrary object as well as information about its structure. Reflection is illustrated in the reflection.go

[maxwell@MaxwellDBA Reflection]$ vim reflection.go   
[maxwell@MaxwellDBA Reflection]$ go run reflection.go
X1 Type: main.t1
X2 Type: main.t2
X3 Type: int
X4 Type: main.aStructure
The fields of main.aStructure are: 
0: Field name: X Type: uint and Value: 123
1: Field name: Y Type: float64 and Value: 3.14
2: Field name: Text Type: string and Value: A structure
[maxwell@MaxwellDBA Reflection]$ cat reflection.go
package main

import (
   "fmt"
   "reflect"
)

func main() {

   // you create two new types ,named t1 and t2,that are both int and three variables , named x1, x2, x3
    type t1 int
    type t2 int

    x1 := t1(1)
    x2 := t2(1)
    x3 := 1

    // you find the type of the x1,x2 and x3 variables using reflect.ValueOf() and Type()
    st1 := reflect.ValueOf(&x1).Elem()
    st2 := reflect.ValueOf(&x2).Elem()
    st3 := reflect.ValueOf(&x3).Elem()

    typeOfX1 := st1.Type()
    typeOfX2 := st2.Type()
    typeOfX3 := st3.Type()


    fmt.Printf("X1 Type: %s\n", typeOfX1)
    fmt.Printf("X2 Type: %s\n", typeOfX2)
    fmt.Printf("X3 Type: %s\n", typeOfX3)


    type aStructure struct {
         X   uint
         Y   float64
         Text string
    }

    x4 := aStructure{123, 3.14, "A structure"}
    st4 := reflect.ValueOf(&x4).Elem()
    typeOfX4 := st4.Type()

    fmt.Printf("X4 Type: %s\n", typeOfX4)
    fmt.Printf("The fields of %s are: \n", typeOfX4)

    for i := 0; i < st4.NumField(); i++ {
          fmt.Printf("%d: Field name: %s ", i, typeOfX4.Field(i).Name)
          fmt.Printf("Type: %s ", st4.Field(i).Type())
          fmt.Printf("and Value: %v\n", st4.Field(i).Interface())
    }
}

[maxwell@MaxwellDBA Reflection]$ 

Calling C code from Go

you can start by visiting the documentation of the cgo tool at https://golang.org/cmd/cgo/

as well as by looking at the code found at https://github.com/golang/go/blob/master/misc/cgo/gmp/gmp.go

Unsafe code

Using unsafe code can be dangerous for your programs, so only use it when it is absolutely necessary. If you are not completely sure that you need it, then do not use it.

[maxwell@MaxwellDBA unsafecode]$ vim unsafe.go
[maxwell@MaxwellDBA unsafecode]$ go run unsafe.go
*p1:  5
*p2:  5
312121321321213212
*p2:  606940444
31212132
*p2:  31212132
[maxwell@MaxwellDBA unsafecode]$ cat unsafe.go
package main

import (
   "fmt"
   "unsafe"
)


func main() {
   var value int64 = 5
   var p1 = &value
   var p2 = (*int32)(unsafe.Pointer(p1))

   fmt.Println("*p1: ", *p1)
   fmt.Println("*p2: ", *p2)
   *p1 = 312121321321213212
   fmt.Println(value)
   fmt.Println("*p2: ", *p2)
   *p1 = 31212132
   fmt.Println(value)
   fmt.Println("*p2: ", *p2)
}
[maxwell@MaxwellDBA unsafecode]$

Comparing Go to other programming languages

C:

  • the most popular programming language for developing systems software due to the portable part of each Unix operating system is written in C.
  • Critical drawbacks: C pointers. which are great and fast, can lead to difficult-to-detect bugs and memory leaks.
  • C does not offer garbage collection.

C++

  • Have good support for cocurrent programming

Rust:

  • Rust is a new systems programming language that tries to avoid unpleasant bugs caused by unsafe code.

Swift:

  • Swift is more suitable for developing systems software for macOS systems.

Python:

  • Python is a scripting language, which is its main disadvantage. This is because ususally, you do not want to make the source of your system software available to everyone.

Perl:

  • What was said about Python can be also said Perl.

If you cannot choose between Go and Rust, then just try C. Learning the basics of systems programming is more important than the programming language you select.

Analysing software

Remember that although dtrace(1) is more powerful than strace(1) and has its own programming language. strace(1) is more versatile for watching the system calls a program makes.

Using the strace(1) command-line utility

The strace(1) command-line utility allows you to trace system calls and signals.

The number after the name of a program refers to the section of the manual its page belongs to. Although most of the names can be found only once, which means that putting the section number is not necessary, there are names that can be located in multiple sections because they have multiple meanings, such as crontab(1) and crontab(5). Therefore, if you try to retrieve such a page without specifically stating the section number, you will get the entry in the section of the manual that has the smallest section number.

[maxwell@MaxwellDBA goproject]$ strace ./addCLAImproved.go 1 2 2>&1 | grep write

The DTrace utility

This subsection will use the dtruss(1) command-line utility, which is just a dtrace(1) script, that shows the system calls of a process.

sudo dtruss -c ./addCLAImproved 2000 2>&1 | grep write

Starting to realize that not all Unix systems work the same way, despite their numerous similarities, is marvelous. But this also means that you should not make any assumptions about the way a Unix system works behind the scenes.

The dtrace(1) utility is much more powerful than strace(1) and has its own programming language but is more difficult to learn. Additionally, even though there is a Linux version of dtrace(1), strace(1) is more mature on Linux systems and does the job of tracing system calls in a simpler way.

Unreachable code

Unreachable code is code that can never be executed and is a logical kind of error.

You should not confuse unreachable code with code that never gets executed intentionally, such as the code of a function that is not needed and is therefore not called in a program.

[maxwell@MaxwellDBA unreachablecode]$ vim cannotReach.go        
[maxwell@MaxwellDBA unreachablecode]$ go tool vet cannotReach.go
cannotReach.go:9: unreachable code
cannotReach.go:15: unreachable code
[maxwell@MaxwellDBA unreachablecode]$ cat cannotReach.go
package main

import (
   "fmt"
)

func x() int {
   return -1
   fmt.Println("Exiting x()")
   return -1
}

func y() int {
   return -1
   fmt.Println("Exiting y()")
   return -1
}

func main(){
   fmt.Println(x())
   fmt.Println("Exiting program...")
}
[maxwell@MaxwellDBA unreachablecode]$ 

Summary

some advanced Go features, including error handling, pattern matching and regular expressions, reflection, and unsafe code. Also, it talked about the strace(1) and dtrace(1) tools.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值