开始用go-ffmpeg这个包,本来它处理视频获得封面图片没问题,可能用了最新的ffmpeg8.1版本,导致pip:管道出错,可能是视频格式导致无法使用管道功能。它好处是将图片存在内存中,调用它之后,再将内存里的保存到文件中去。但可惜用不了了,直接用cmd那个调用ffmpeg来导出图片文件保存。
ffprobe读取视频的GPS信号也挺好使,go-ffmpeg里也有对应的方法,并且也返回了json数据,由于不必多一个go-ffmpeg,所以干脆probe也直接用命令调用,也能获得返回string,建立golang的struct数据结构,将返回的string转换成json格式即可。
对于&和始终无法理解。在方法里,定义个变量为&model.struct后,可以赋值,但是定义model.struct,无法将变量值赋给它。理论见下文,来自bing搜索的答复

    // var gpsData *models.GPSData——这样定义跟下一行什么区别???这样定义的话,下文无法将float64赋值给gpsData.Latitude
    gpsData := &models.GPSData{Valid: false}
…………
        latitude, err := strconv.ParseFloat(strings.Replace(match[0], "+", "", -1), 64)
        if err != nil {
            logs.Error(err)
        }
        // logs.Info(latitude)
        gpsData.Latitude = latitude // 纬度——如果是第一种定义方法,这里会出错,提示空错误
…………
    // 保存到数据库
    uploadedFile := &models.MapUploadedFile{
        // 项目ID,用户ID
        ProjectID:  projectID,
        HasGPS:     gpsData.Valid,
        Latitude:   gpsData.Latitude,

Go语言中的 & 和 *

先明确一个前提:什么是指针?
指针是一种变量,它存储的不是具体的值,而是另一个变量的内存地址。
比如变量 a 的值是 10,存储在内存地址 0x1234 中,那么指针 p 可以存储 0x1234,此时我们说「p 指向 a」。
qin:定义*变量能赋真实值和变量;&map元素可以赋变量?*map元素不能赋变量?

  1. &:取地址符(获取变量的内存地址)
    & 作用在一个变量上,返回该变量的内存地址(是一个指针值)。
package main

import "fmt"

func main() {
    a := 10
    fmt.Println(a)   // 输出:10(变量a的值)
    fmt.Println(&a)  // 输出:0xc00001a0a8(变量a的内存地址,每次运行可能不同)
}

这里 &a 就得到了 a 的内存地址,这个地址可以赋值给一个指针变量。

  1. *:有两种用法
    * 的含义取决于它出现的场景,主要有两种:
    场景1:声明指针类 型(定义一个指针变量)
    在变量类型前加 *,表示这是一个「指向该类型变量的指针」。

示例:

package main

import "fmt"

func main() {
    a := 10

    // 声明一个指向int类型的指针变量p
    var p *int  // p是指针类型,此时p的值为nil(空指针)

    p = &a  // 把a的地址赋值给p,此时p指向a
    fmt.Println(p)  // 输出:0xc00001a0a8(和&a的值相同,都是a的地址)

    p1 := &a  // p是指向a的指针

    fmt.Println(*p1)  // 输出:10(通过指针p获取a的值,解引用)

    // 通过指针修改指向的变量值
    *p1 = 20
    fmt.Println(a)  // 输出:20(a的值被修改了)
}

场景2:指针解引用(通过指针获取指向的变量值)
*作用在一个指针变量上时,表示「获取该指针指向的变量的值」,这个操作叫「解引用」。

package main

import "fmt"

func main() {
    a := 10
    p := &a  // p是指向a的指针

    fmt.Println(*p)  // 输出:10(通过指针p获取a的值,解引用)

    // 通过指针修改指向的变量值
    *p = 20
    fmt.Println(a)  // 输出:20(a的值被修改了)
    p = a // 这里赋值变量行吗???cannot use a (variable of type int) as *int value in assignment
}

场景B:函数参数传递(值传递 vs 指针传递)
Go 语言中函数参数默认是「值传递」(传递副本),如果想在函数内部修改外部变量,需要传递指针(内存地址)。

package main
import "fmt"
// 函数参数是普通int类型(值传递)
func modify1(x int) {
    x = 100  // 只能修改副本,不影响外部变量
}

// 函数参数是*int类型(指针传递)
func modify2(x *int) {
    *x = 100  // 通过解引用修改指针指向的外部变量
}

func main() {
    a := 10
    modify1(a)
    fmt.Println(a)  // 输出:10(未被修改)

    modify2(&a)     // 传递a的地址(&取地址)
    fmt.Println(a)  // 输出:100(被修改了)
}
作者:秦晓川  创建时间:2026-05-06 23:26
最后编辑:秦晓川  更新时间:2026-05-12 22:55