Go 语言同一个包内函数调用、包名和实际路径最后一个目录不一致问题

以下代码的 GOPATH 路径为 "/home/wohu/GoCode"

1. 同一个包内的函数可以相互调用

代码结构如下:

wohu@wohu:~/GoCode/src$ tree temp
temp
├── chapter
│   ├── demo1
│   │   ├── demo1.go
│   │   └── demo1_lib.go

demo1.go 源码如下:

package main

func main() {
	name := "wohu"
	hello(name) // 调用以小写字母开头的同一个包内的函数
}

demo1_lib.go 源码如下:

package main

import "fmt"

// hello() 函数名称为小写开头
func hello(name string) {
	fmt.Printf("Hello, %s!\n", name)
}

运行结果:

[Running] cd "/home/wohu/GoCode/src/temp/chapter/demo1/" && go run .
Hello, wohu!

可以看到包内的函数是可以被包内其它任意函数调用的。

2. 包名和实际路径最后一个目录一致

代码目录结构如下:

wohu@wohu:~/GoCode/src$ tree temp
temp
├── chapter
│   ├── demo2
│   │   ├── demo2.go
│   │   └── lib
│   │       └── demo2_lib.go

demo2.go 源码如下:

package main

import (
	"temp/chapter/demo2/lib"     
)

func main() {
	name := "wohu"
	lib.Hello(name) // 直接使用 包名.函数名称来调用函数
}

其中导入 demo2_lib.go 所在的相对 GOPATH 路径为 "temp/chapter/demo2/lib"

demo2_lib.go 源码如下:

package lib // 包名和实际路径中最后一个文件夹名称相同

import "fmt"

func Hello(name string) {
	fmt.Printf("Hello, %s!\n", name)
}

运行结果:

[Running] cd "/home/wohu/GoCode/src/temp/chapter/demo2/" && go run .
Hello, wohu!

3. 包名和实际路径最后一个目录不一致

同样的目录结构

wohu@wohu:~/GoCode/src$ tree temp
temp
├── chapter
│   ├── demo2
│   │   ├── demo2.go
│   │   └── lib
│   │       └── demo2_lib.go

demo2_lib.go 代码, 声明其包名为 lib2

package lib2

import "fmt"

func Hello(name string) {
   fmt.Printf("Hello, %s!\n", name)
}

修改 demo2.go 代码如下

package main

import (
	"temp/chapter/demo2/lib"
)

func main() {
	name := "wohu"
	lib.Hello(name)
}

运行出错:

[Running] cd "/home/wohu/GoCode/src/temp/chapter/demo2/" && go run .
# temp/chapter/demo2
./demo2.go:4:2: imported and not used: "temp/chapter/demo2/lib" as lib2
./demo2.go:9:2: undefined: lib

为什么会是这样?根本原因就是,我们在源码文件中声明所属的代码包与其所在目录的名称不同。

请记住,源码文件所在的目录相对于 src 目录的相对路径就是它的代码包导入路径,而实际使用其程序实体时给定的限定符(本示例代码中的 lib )要与它声明所属的代码包名称对应。

重要: import 后面的最后一个元素其实是目录名而不是包名!!!

而如下修改,

package main

import (
	"temp/chapter/demo2/lib2"
)

func main() {
	name := "wohu"
	lib2.Hello(name)
}

运行报错:

[Running] cd "/home/wohu/GoCode/src/temp/chapter/demo2/" && go run .
demo2.go:4:2: cannot find package "temp/chapter/demo2/lib2" in any of:
	/usr/local/go/src/temp/chapter/demo2/lib2 (from $GOROOT)
	/home/wohu/GoCode/src/temp/chapter/demo2/lib2 (from $GOPATH)

从提示的错误信息可以看到是因为没有找到 "temp/chapter/demo2/lib2" 目录。

继续使用别名修改

package main

import (
	p "temp/chapter/demo2/lib"
)

func main() {
	name := "wohu"
	p.Hello(name)
}

或者

package main

import (
	"temp/chapter/demo2/lib"
)

func main() {
	name := "wohu"
	lib2.Hello(name)
}

即在 import 时导入的是目录名,而在外部进行调用时需要使用包名作为前缀 lib2.Hello(name)

import "目录名"
包名.Hello()

因此,为了不让该代码包的使用者产生困惑,我们总是应该让声明的包名与其父目录的名称一致。

包名和目录名不一致时需要注意:

  • 目录名使用在文件层面,例如库的安装路径名、库文件名以及被导入时的路径;
  • 包名使用在代码层面,例如调用包的函数时;
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 下面是一个示例代码,它使用了 A* 搜索算法来找到离目标点 B 最近的点。在这里,我们假设 A 点和 B 点的坐标都是 (x, y) 形式的整数坐标。 ``` package main import ( "fmt" "math" ) type Point struct { x, y int } func (p Point) Distance(target Point) float64 { return math.Sqrt(math.Pow(float64(p.x-target.x), 2) + math.Pow(float64(p.y-target.y), 2)) } func (p Point) NextPoints() []Point { // 这里是扩展点的代码,它返回周围可以走到的点 return []Point{ {p.x + 1, p.y}, {p.x - 1, p.y}, {p.x, p.y + 1}, {p.x, p.y - 1}, } } func (p Point) String() string { return fmt.Sprintf("(%d, %d)", p.x, p.y) } func astar(start, target Point) ([]Point, float64) { // closedSet是已经走过的点,openSet是下一步要走的点 closedSet := make(map[Point]bool) openSet := map[Point]float64{start: start.Distance(target)} // parents用来记录每个点的父结点,用于最后打印路径 parents := make(map[Point]Point) for len(openSet) > 0 { // 找到f值最小的点 current := Point{} f := math.MaxFloat64 for point, pointF := range openSet { if pointF < f { current = point f = pointF } } // 如果当前点是目标点,打印路径 if current == target { path := []Point{} for current != start { path = append([]Point{current}, path...) current = parents[current] } return append([]Point{start}, path...), f } // 从openSet中删除,加入closedSet delete(openSet, current) closedSet[current] = ### 回答2: 使用Golang编写一个代码实现A点10格范围内离B点最近的点的启发式搜索。 首先,我们需要定义两个点的结构体:Point和Distance。 ```go type Point struct { X, Y int } type Distance struct { Point Point D int } ``` 然后,我们可以编写一个函数来计算两个点之间的欧几里得距离。 ```go func calcDistance(p1, p2 Point) int { return (p1.X-p2.X)*(p1.X-p2.X) + (p1.Y-p2.Y)*(p1.Y-p2.Y) } ``` 接下来,我们可以编写一个函数来实现启发式搜索,找到A点10格范围内离B点最近的点。 ```go func findNearestPoint(A, B Point) Point { minDistance := math.MaxInt32 nearestPoint := Point{} for i := A.X - 10; i <= A.X+10; i++ { for j := A.Y - 10; j <= A.Y+10; j++ { if i >= 0 && i < mapWidth && j >= 0 && j < mapHeight { currentPoint := Point{i, j} currentDistance := calcDistance(currentPoint, B) if currentDistance < minDistance { minDistance = currentDistance nearestPoint = currentPoint } } } } return nearestPoint } ``` 在这个函数中,我们遍历A点10格范围内的所有点,计算每个点到B点的距离,并更新最近距离和最近点的值。 最后,我们可以在主函数中调用这个函数,并打印出结果。 ```go func main() { A := Point{1, 1} B := Point{5, 5} nearestPoint := findNearestPoint(A, B) fmt.Println(nearestPoint) } ``` 这个代码将会打印出在A点10格范围内离B点最近的点的坐标。 请注意,上述代码只是一个简单的示例,具体实现可能需要根据实际需求进行调整和优化。 ### 回答3: 使用golang编写一个代码,通过启发式搜索算法找出在A点10格范围内离B点最近的点。 首先,我们需要定义一个表示点的结构体,包含点的坐标x和y。代码如下: type Point struct { x, y int } 接下来,我们需要实现一个函数来计算两点之间的欧氏距离。代码如下: func Distance(p1, p2 Point) float64 { dx := p1.x - p2.x dy := p1.y - p2.y return math.Sqrt(float64(dx*dx + dy*dy)) } 接下来,我们可以编写启发式搜索函数,通过遍历A点10格范围内的所有点,计算每个点到B点的距离并保存最小距离的点。代码如下: func FindNearestPoint(A, B Point) Point { minDist := math.Inf(1) var nearestPoint Point for i := A.x - 10; i <= A.x+10; i++ { for j := A.y - 10; j <= A.y+10; j++ { currentPoint := Point{i, j} dist := Distance(currentPoint, B) if dist < minDist { minDist = dist nearestPoint = currentPoint } } } return nearestPoint } 最后,我们可以在main函数中调用FindNearestPoint函数,并输出结果。代码如下: func main() { A := Point{2, 3} B := Point{5, 7} nearestPoint := FindNearestPoint(A, B) fmt.Println("离B点最近的点是:", nearestPoint) } 以上代码使用启发式搜索算法,遍历A点10格范围内的所有点,计算每个点到B点的距离,然后返回最小距离的点。输出结果为离B点最近的点的坐标。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值