Golang跨功能数据传输的实现方法

Golang跨功能数据传输的实现方法 我有两个函数,根据第二个函数的结果,我希望第一个函数执行一个操作。在 Go 语言中有解决这个问题的方案吗?

示例:

  1. 第一个函数:在一个扫描论坛的系统中获取论坛 URL。
  2. 第二个函数:扫描论坛帖子,并获取最近一次发帖的时间。

我的目标:如果论坛帖子的最后发帖日期超过一年,我希望终止浏览并搜索其他论坛链接。因此,根据我从第二个函数获得的数据,我希望调用我的第一个函数“继续”。

提前感谢您的帮助。

1 回复

更多关于Golang跨功能数据传输的实现方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go中实现跨函数数据传输和控制流,有几种常见方案。以下是针对你场景的具体实现:

方案1:返回值传递 + 控制逻辑

package main

import (
    "fmt"
    "time"
)

// 第一个函数:获取论坛URL
func getForumURLs() []string {
    return []string{
        "https://forum.example1.com",
        "https://forum.example2.com",
        "https://forum.example3.com",
    }
}

// 第二个函数:扫描论坛并返回最后发帖时间
func scanForum(url string) (time.Time, error) {
    // 模拟扫描逻辑
    lastPostTimes := map[string]time.Time{
        "https://forum.example1.com": time.Now().AddDate(-2, 0, 0), // 2年前
        "https://forum.example2.com": time.Now().AddDate(0, -3, 0), // 3个月前
        "https://forum.example3.com": time.Now().AddDate(-1, -1, 0), // 1年1个月前
    }
    
    if lastPost, exists := lastPostTimes[url]; exists {
        return lastPost, nil
    }
    return time.Time{}, fmt.Errorf("forum not found")
}

func main() {
    urls := getForumURLs()
    
    for _, url := range urls {
        lastPostTime, err := scanForum(url)
        if err != nil {
            fmt.Printf("扫描 %s 失败: %v\n", url, err)
            continue
        }
        
        // 检查是否超过一年
        if time.Since(lastPostTime) > 365*24*time.Hour {
            fmt.Printf("论坛 %s 最后发帖时间超过一年,跳过\n", url)
            continue // 继续下一个论坛
        }
        
        fmt.Printf("论坛 %s 最近有活动,最后发帖: %v\n", url, lastPostTime)
    }
}

方案2:使用通道进行通信

package main

import (
    "fmt"
    "time"
)

func getForumURLs(urlChan chan<- string) {
    urls := []string{
        "https://forum.example1.com",
        "https://forum.example2.com",
        "https://forum.example3.com",
    }
    
    for _, url := range urls {
        urlChan <- url
    }
    close(urlChan)
}

func scanForum(url string, resultChan chan<- time.Time) {
    lastPostTimes := map[string]time.Time{
        "https://forum.example1.com": time.Now().AddDate(-2, 0, 0),
        "https://forum.example2.com": time.Now().AddDate(0, -3, 0),
        "https://forum.example3.com": time.Now().AddDate(-1, -1, 0),
    }
    
    if lastPost, exists := lastPostTimes[url]; exists {
        resultChan <- lastPost
    } else {
        resultChan <- time.Time{}
    }
}

func main() {
    urlChan := make(chan string, 10)
    resultChan := make(chan time.Time, 10)
    
    go getForumURLs(urlChan)
    
    for url := range urlChan {
        go scanForum(url, resultChan)
        
        lastPostTime := <-resultChan
        if lastPostTime.IsZero() {
            fmt.Printf("无法获取 %s 的发帖时间\n", url)
            continue
        }
        
        if time.Since(lastPostTime) > 365*24*time.Hour {
            fmt.Printf("论坛 %s 最后发帖时间超过一年,跳过\n", url)
            continue
        }
        
        fmt.Printf("论坛 %s 最近有活动,最后发帖: %v\n", url, lastPostTime)
    }
}

方案3:回调函数模式

package main

import (
    "fmt"
    "time"
)

type ForumScanner struct {
    shouldContinue func(time.Time) bool
}

func (fs *ForumScanner) getForumURLs() []string {
    return []string{
        "https://forum.example1.com",
        "https://forum.example2.com",
        "https://forum.example3.com",
    }
}

func (fs *ForumScanner) scanForum(url string) (time.Time, error) {
    lastPostTimes := map[string]time.Time{
        "https://forum.example1.com": time.Now().AddDate(-2, 0, 0),
        "https://forum.example2.com": time.Now().AddDate(0, -3, 0),
        "https://forum.example3.com": time.Now().AddDate(-1, -1, 0),
    }
    
    if lastPost, exists := lastPostTimes[url]; exists {
        return lastPost, nil
    }
    return time.Time{}, fmt.Errorf("forum not found")
}

func (fs *ForumScanner) processForums() {
    urls := fs.getForumURLs()
    
    for _, url := range urls {
        lastPostTime, err := fs.scanForum(url)
        if err != nil {
            fmt.Printf("扫描 %s 失败: %v\n", url, err)
            continue
        }
        
        if !fs.shouldContinue(lastPostTime) {
            fmt.Printf("论坛 %s 最后发帖时间超过一年,跳过\n", url)
            continue
        }
        
        fmt.Printf("论坛 %s 最近有活动,最后发帖: %v\n", url, lastPostTime)
    }
}

func main() {
    scanner := &ForumScanner{
        shouldContinue: func(lastPostTime time.Time) bool {
            return time.Since(lastPostTime) <= 365*24*time.Hour
        },
    }
    
    scanner.processForums()
}

方案4:使用context控制流程

package main

import (
    "context"
    "fmt"
    "time"
)

func getForumURLs(ctx context.Context) <-chan string {
    urlChan := make(chan string)
    
    go func() {
        defer close(urlChan)
        
        urls := []string{
            "https://forum.example1.com",
            "https://forum.example2.com",
            "https://forum.example3.com",
        }
        
        for _, url := range urls {
            select {
            case <-ctx.Done():
                return
            case urlChan <- url:
            }
        }
    }()
    
    return urlChan
}

func scanForum(ctx context.Context, url string) (time.Time, bool) {
    lastPostTimes := map[string]time.Time{
        "https://forum.example1.com": time.Now().AddDate(-2, 0, 0),
        "https://forum.example2.com": time.Now().AddDate(0, -3, 0),
        "https://forum.example3.com": time.Now().AddDate(-1, -1, 0),
    }
    
    if lastPost, exists := lastPostTimes[url]; exists {
        return lastPost, true
    }
    return time.Time{}, false
}

func main() {
    ctx := context.Background()
    
    for url := range getForumURLs(ctx) {
        lastPostTime, found := scanForum(ctx, url)
        if !found {
            fmt.Printf("无法获取 %s 的发帖时间\n", url)
            continue
        }
        
        if time.Since(lastPostTime) > 365*24*time.Hour {
            fmt.Printf("论坛 %s 最后发帖时间超过一年,跳过\n", url)
            continue
        }
        
        fmt.Printf("论坛 %s 最近有活动,最后发帖: %v\n", url, lastPostTime)
    }
}

这些方案都能实现你的需求:根据第二个函数(scanForum)的扫描结果,控制第一个函数(getForumURLs)的继续执行。方案1最简单直接,方案2适合并发场景,方案3提供了更好的扩展性,方案4适合需要取消和超时控制的场景。

回到顶部