day7函数 函数值 练习5.7
							parent
							
								
									69b221e562
								
							
						
					
					
						commit
						23d290d7b8
					
				|  | @ -0,0 +1,66 @@ | ||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"Study/src/study/day7Function/HtmlTools" | ||||||
|  | 	"fmt" | ||||||
|  | 	"golang.org/x/net/html" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // 在go中 函数也是一类值,类似于int,具体的数值就是int的值
 | ||||||
|  | // 和其他值一样,函数也拥有类型,可以赋值给某一个相同类型的变量。
 | ||||||
|  | // 也可以作为函数的参数 和返回值被传递。
 | ||||||
|  | 
 | ||||||
|  | func Add(x *int)   { *x++ } | ||||||
|  | func Minus(x *int) { *x-- } | ||||||
|  | 
 | ||||||
|  | func main() { | ||||||
|  | 	A := Add | ||||||
|  | 	B := Minus | ||||||
|  | 	num := 1 | ||||||
|  | 	fmt.Println(num) // 1
 | ||||||
|  | 	A(&num) | ||||||
|  | 	fmt.Println(num) // 2
 | ||||||
|  | 	B(&num) | ||||||
|  | 	fmt.Println(num) // 1
 | ||||||
|  | 
 | ||||||
|  | 	// strings.Map对字符串中的每个字符调用add1函数,
 | ||||||
|  | 	// 并将每个add1函数的返回值组成一个新的字符串返回给调用者。
 | ||||||
|  | 	var add1 = func(r rune) rune { return r + 1 } | ||||||
|  | 	fmt.Println(strings.Map(add1, "HAL-9000")) // "IBM.:111"
 | ||||||
|  | 	fmt.Println(strings.Map(add1, "VMS"))      // "WNT"
 | ||||||
|  | 	fmt.Println(strings.Map(add1, "Admix"))    // "Benjy"
 | ||||||
|  | 
 | ||||||
|  | 	// forEachNode针对每个结点x,都会调用pre(x)和post(x)。
 | ||||||
|  | 	// pre和post都是可选的。
 | ||||||
|  | 	// 遍历孩子结点之前,pre被调用
 | ||||||
|  | 	// 遍历孩子结点之后,post被调用
 | ||||||
|  | 	var forEachNode func(n *html.Node, pre, post func(n *html.Node)) | ||||||
|  | 	forEachNode = func(n *html.Node, pre, post func(n *html.Node)) { | ||||||
|  | 		if pre != nil { | ||||||
|  | 			pre(n) | ||||||
|  | 		} | ||||||
|  | 		for c := n.FirstChild; c != nil; c = c.NextSibling { | ||||||
|  | 			forEachNode(c, pre, post) | ||||||
|  | 		} | ||||||
|  | 		if post != nil { | ||||||
|  | 			post(n) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var depth int | ||||||
|  | 	startElement := func(n *html.Node) { | ||||||
|  | 		if n.Type == html.ElementNode { | ||||||
|  | 			fmt.Printf("%*s<%s>\n", depth*2, "", n.Data) | ||||||
|  | 			depth++ | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	endElement := func(n *html.Node) { | ||||||
|  | 		if n.Type == html.ElementNode { | ||||||
|  | 			depth-- | ||||||
|  | 			fmt.Printf("%*s</%s>\n", depth*2, "", n.Data) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	forEachNode(HtmlTools.GetHtml(), startElement, endElement) | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,28 @@ | ||||||
|  | package HtmlTools | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"golang.org/x/net/html" | ||||||
|  | 	"log" | ||||||
|  | 	"net/http" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func GetHtml() *html.Node { | ||||||
|  | 	resp, err := http.Get("https://golang-china.github.io/gopl-zh/ch5/ch5-02.html") | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 	if resp.StatusCode != http.StatusOK { | ||||||
|  | 		err := resp.Body.Close() | ||||||
|  | 		if err != nil { | ||||||
|  | 			log.Fatal(err) | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	doc, err := html.Parse(resp.Body) | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return doc | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -14,14 +14,6 @@ func BothAdd(a, b int, action func(nun int) int) (int, int, error) { | ||||||
| 	} | 	} | ||||||
| 	return action(a), action(b), nil | 	return action(a), action(b), nil | ||||||
| } | } | ||||||
| func Add(num int) int { |  | ||||||
| 	num++ |  | ||||||
| 	return num |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| func PointAdd(num *int) { |  | ||||||
| 	*num++ |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| func Concat2(a string, bOptional ...int) string { | func Concat2(a string, bOptional ...int) string { | ||||||
| 	b := 5 | 	b := 5 | ||||||
|  | @ -58,8 +50,5 @@ func main() { | ||||||
| 	time.Sleep(time.Second * 20) | 	time.Sleep(time.Second * 20) | ||||||
| 	//fmt.Println(Sum[int](1, 2))
 | 	//fmt.Println(Sum[int](1, 2))
 | ||||||
| 	//fmt.Println(Sum(1.23, 2.3))
 | 	//fmt.Println(Sum(1.23, 2.3))
 | ||||||
| 	//number := 233
 |  | ||||||
| 	//PointAdd(&number)
 |  | ||||||
| 	//fmt.Println(number)
 |  | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,83 @@ | ||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"Study/src/study/day7Function/HtmlTools" | ||||||
|  | 	"fmt" | ||||||
|  | 	"golang.org/x/net/html" | ||||||
|  | 	"reflect" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func main() { | ||||||
|  | 	// 同样的,函数可以作为参数传入另一个函数
 | ||||||
|  | 	// forEachNode针对每个结点x,都会调用pre(x)和post(x)。
 | ||||||
|  | 	// pre和post都是可选的。
 | ||||||
|  | 	// 遍历孩子结点之前,pre被调用
 | ||||||
|  | 	// 遍历孩子结点之后,post被调用
 | ||||||
|  | 	var forEachNode func(n *html.Node, pre, post func(n *html.Node)) | ||||||
|  | 	forEachNode = func(n *html.Node, pre, post func(n *html.Node)) { | ||||||
|  | 		if pre != nil { | ||||||
|  | 			pre(n) | ||||||
|  | 		} | ||||||
|  | 		for c := n.FirstChild; c != nil; c = c.NextSibling { | ||||||
|  | 			forEachNode(c, pre, post) | ||||||
|  | 		} | ||||||
|  | 		if post != nil { | ||||||
|  | 			post(n) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	var depth int | ||||||
|  | 	var ExcludeNodes []string = []string{ | ||||||
|  | 		"link", | ||||||
|  | 		"img", | ||||||
|  | 		"meta", | ||||||
|  | 	} | ||||||
|  | 	// 断言
 | ||||||
|  | 	m, _ := ToMapSetStrictE(ExcludeNodes) | ||||||
|  | 	ExcludeNodesMap := m.(map[string]struct{}) | ||||||
|  | 	startElemen := func(n *html.Node) { | ||||||
|  | 		if n.Type == html.ElementNode { | ||||||
|  | 			fmt.Printf("%*s<%s", depth*2, "", n.Data) | ||||||
|  | 			for _, attr := range n.Attr { | ||||||
|  | 				fmt.Printf(" %s=\"%s\"", attr.Key, attr.Val) | ||||||
|  | 			} | ||||||
|  | 			// 检测单节点
 | ||||||
|  | 			if _, ok := ExcludeNodesMap[n.Data]; ok { | ||||||
|  | 				fmt.Println(" />") | ||||||
|  | 			} else { | ||||||
|  | 				fmt.Println(">") | ||||||
|  | 			} | ||||||
|  | 			depth++ | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	endElement := func(n *html.Node) { | ||||||
|  | 		if n.Type == html.ElementNode { | ||||||
|  | 			depth-- | ||||||
|  | 			// 检测单节点
 | ||||||
|  | 			if _, ok := ExcludeNodesMap[n.Data]; !ok { | ||||||
|  | 				fmt.Printf("%*s</%s>\n", depth*2, "", n.Data) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	forEachNode(HtmlTools.GetHtml(), startElemen, endElement) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 借助一个空接口,使切片转为map
 | ||||||
|  | func ToMapSetStrictE(i interface{}) (interface{}, error) { | ||||||
|  | 	// check param
 | ||||||
|  | 	if i == nil { | ||||||
|  | 		return nil, fmt.Errorf("unable to converts %#v of type %T to map[interface{}]struct{}", i, i) | ||||||
|  | 	} | ||||||
|  | 	t := reflect.TypeOf(i) | ||||||
|  | 	kind := t.Kind() | ||||||
|  | 	if kind != reflect.Slice && kind != reflect.Array { | ||||||
|  | 		return nil, fmt.Errorf("the input %#v of type %T isn't a slice or array", i, i) | ||||||
|  | 	} | ||||||
|  | 	// execute the convert
 | ||||||
|  | 	v := reflect.ValueOf(i) | ||||||
|  | 	mT := reflect.MapOf(t.Elem(), reflect.TypeOf(struct{}{})) | ||||||
|  | 	mV := reflect.MakeMapWithSize(mT, v.Len()) | ||||||
|  | 	for j := 0; j < v.Len(); j++ { | ||||||
|  | 		mV.SetMapIndex(v.Index(j), reflect.ValueOf(struct{}{})) | ||||||
|  | 	} | ||||||
|  | 	return mV.Interface(), nil | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue