更好的方式来表达Go中的函数(结构体方法)

huangapple go评论63阅读模式
英文:

better way to express a function in Go (Struct methods)

问题

这是一个遍历Point数组的函数。Point是一个包含x和y两个int类型元素的结构体。traverse函数从另一个函数中调用,并传入dir的值。循环开始处的if检查可以避免,因为一旦函数被调用,dir的值就不会改变。有没有更好的方法在Go语言中表达这个逻辑?结构体方法返回一个Point。我提供了一个结构体方法的示例。

type Point struct {
	x int
	y int
}

func (p Point) next_row() Point {
	nearby := Point{p.x + 1, p.y}
	return nearby
}

func trv_point(p Point, p_list []Point, dir string) int {
	seg_count := 0
	var nearby Point
	for {
		if dir == "up" {
			nearby = p.prev_row()
		}
		if dir == "down" {
			nearby = p.next_row()
		}
		if dir == "left" {
			nearby = p.prev_col()
		}
		if dir == "right" {
			nearby = p.next_col()
		}

		if !check_point_in_slice(p_list, nearby) {
			break
		}
		seg_count++
		p = nearby

	}
	return seg_count
}
英文:

This is a function to traverse an array of Points. A Point is a struct with elements x and y of type int. The traverse function is called from another function with a value of dir. The if check at the beginning of the loop can be avoided because the dir value, once the function is called, does not change. Is there a better way to express this logic in Go? The struct method returns a Point. I have provided one example of the struct method.

type Point struct {
	x int
	y int
}

func (p Point) next_row() Point {
	nearby := Point{p.x + 1, p.y}
	return nearby
}

func trv_point(p Point, p_list []Point, dir string) int {
	seg_count := 0
	var nearby Point
	for {
		if dir == "up" {
			nearby = p.prev_row()
		}
		if dir == "down" {
			nearby = p.next_row()
		}
		if dir == "left" {
			nearby = p.prev_col()
		}
		if dir == "right" {
			nearby = p.next_col()
		}

		if !check_point_in_slice(p_list, nearby) {
			break
		}
		seg_count++
		p = nearby

	}
	return seg_count
}

答案1

得分: 2

因为这里的dir没有改变,所以那些if语句是多余的,而且你应该在这种情况下使用if-else语句,因为只有一个方向("up"、"down"、"left"、"right")可能发生。

首先看一下这个例子:

type Point struct {
	x int
	y int
}

func (p *Point) next_row() {
	p.x += 1
}

func main() {
	p := Point{0, 0}
	f := p.next_row

	for i := 0; i < 2; i++ {
		fmt.Println(p)
		f()
	}
	fmt.Println(p)
}

输出将是:

{0 0}
{1 0}
{2 0}

在这里,我们将接收器从(p Point)更改为(p *Point),因为我们希望保存对xy的影响。
根据这个假设,我们可以重写为:

type Point struct {
	x int
	y int
}

func (p *Point) next_row() {
	p.x += 1
}

func get_move(dir string) func() {
	var f func()
	switch dir {
	case "up":
		f = p.prev_row
	case "down":
		f = p.next_row
	case "left":
		f = p.prev_col
	case "right":
		f = p.next_col
	}
	return f
}

func trv_point(p Point, p_list []Point, dir string) int {
	seg_count := 0
	var nearby Point
	f := get_move(dir)
	for check_point_in_slice(p_list, p) {
		f()
		seg_count++
	}
	return seg_count
}
英文:

Because the dir is not change here, those if statements are redundent, also you should use if-else statments for this case because just one of the ["up", "down", "left", "right"] could happened.
First look to this example:

type Point struct {
	x int
	y int
}

func (p *Point) next_row() {
	p.x += 1
}

func main() {
	p := Point{0, 0}
	f := p.next_row

	for i := 0; i &lt; 2; i++ {
		fmt.Println(p)
		f()
	}
	fmt.Println(p)
}

the output will be:

{0 0}
{1 0}
{2 0}

Here we change the receiver from (p Point) to (p *Point) because we want to save the effects on x and y.
By this assumption we could rewrite as:

type Point struct {
	x int
	y int
}

func (p *Point) next_row() {
	p.x += 1
}

func get_move(dir string) func() {
	var f func()
	switch dir {
	case &quot;up&quot;:
		f = p.prev_row
	case &quot;down&quot;:
		f = p.next_row
	case &quot;left&quot;:
		f = p.prev_col
	case &quot;right&quot;:
		f = p.next_col
	}
	return f
}

func trv_point(p Point, p_list []Point, dir string) int {
	seg_count := 0
	var nearby Point
	f := get_move(dir)
	for check_point_in_slice(p_list, p) {
		f()
		seg_count++
	}
	return seg_count
}

huangapple
  • 本文由 发表于 2022年3月7日 21:34:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/71381894.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定