直接调用 db.Delete(&article) 仅会删除 articles 表中的记录,而不会自动清除多对多关联关系(即 article_tags 连接表中的记录)。

在 GORM 中,对于多对多关联,如果需要同时删除关联关系,需要使用 Association Mode 来额外处理,例如:

// 删除文章所有 Tag 关联(删除连接表中的记录)
db.Model(&article).Association("Tags").Clear()

或者,可以配置数据库中的外键约束(例如添加 ON DELETE CASCADE),不过这需要在数据库层面配置,是另一种实现方式。

什么是回调函数?

回调函数是一种编程模式,指的是将一个函数作为参数传递给另一个函数,并在特定条件或事件发生时由后者调用前者。回调函数允许异步操作和事件驱动的编程。

简单来说:回调函数是你定义好但由别人(通常是系统或其他函数)在适当时候调用的函数。

回调函数的主要特点

  1. 函数作为参数:回调函数通常作为参数传递给另一个函数
  2. 延迟执行:回调函数不会立即执行,而是在特定条件满足时执行
  3. 异步处理:常用于处理异步操作的结果
  4. 解耦:将调用者与被调用者分离,提高代码灵活性

回调函数的例子

1. JavaScript中的简单回调

// 定义一个回调函数
function greeting(name) {
    console.log('Hello ' + name);
}

// 定义一个接收回调的函数
function processUserInput(callback) {
    const name = prompt('Please enter your name.');
    callback(name); // 在适当时候调用回调
}

// 使用回调
processUserInput(greeting);

2. Node.js中的文件读取(异步I/O)

const fs = require('fs');

// 回调函数
function fileReadCallback(err, data) {
    if (err) {
        console.error('Error reading file:', err);
        return;
    }
    console.log('File content:', data);
}

// 异步读取文件,完成后调用回调
fs.readFile('example.txt', 'utf8', fileReadCallback);

3. 事件监听(浏览器DOM事件)

// 回调函数
function handleClick(event) {
    console.log('Button clicked!', event);
}

// 注册回调
document.getElementById('myButton').addEventListener('click', handleClick);

4. 排序中的比较回调

const numbers = [3, 1, 4, 1, 5, 9, 2, 6];

// 使用回调函数定义排序规则
numbers.sort(function(a, b) {
    return a - b; // 升序排序
});

console.log(numbers); // [1, 1, 2, 3, 4, 5, 6, 9]

回调函数的优缺点

优点

  • 实现异步编程
  • 提高代码复用性
  • 解耦调用者和被调用者
  • 适用于事件驱动编程

缺点

  • 回调地狱(Callback Hell):多层嵌套回调使代码难以阅读和维护
  • 错误处理复杂:需要在每个回调中单独处理错误
  • 控制流不直观

回调地狱示例

// 多层嵌套的回调,难以阅读和维护
doSomething(function(result) {
    doSomethingElse(result, function(newResult) {
        doThirdThing(newResult, function(finalResult) {
            console.log('Got the final result:', finalResult);
        }, failureCallback);
    }, failureCallback);
}, failureCallback);

现代JavaScript通常使用Promise或async/await来解决回调地狱问题。

回调函数是编程中非常重要的概念,特别是在JavaScript和Node.js中广泛使用。理解回调函数是掌握异步编程的基础。

缓存问题

  • Git 会缓存跟踪状态,即使添加了忽略规则,已跟踪的文件仍会被继续跟踪
  • 解决方案:

    git rm -r --cached /backend/tmp/
    git add .
    git commit -m "停止跟踪 tmp 目录"

安装

go get github.com/joho/godotenv

// go install github.com/joho/godotenv/cmd/godotenv@latest

使用

将应用程序配置添加到项目根目录中的 .env 文件中:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE

然后,在Go 应用程序中,可以执行以下作

package main

import (
    "log"
    "os"

    "github.com/joho/godotenv"
)

func main() {
  err := godotenv.Load()
  if err != nil {
    log.Fatal("Error loading .env file")
  }

  s3Bucket := os.Getenv("S3_BUCKET")
  secretKey := os.Getenv("SECRET_KEY")

  // now do something with s3 or whatever
}

参考文档:https://github.com/joho/godotenv

问题分析:


函数未导出
在Go语言中,只有首字母大写的标识符(如函数、变量等)才在包外可见。如果希望home函数可以通过service.home调用,需要将其定义为导出的函数:

func Home(c *gin.Context) {
    c.JSON(200, gin.H{"message": "hello world"})
}

这样,主程序可以通过service.Home访问它。小写函数home是私有的,主程序无法访问。