使用泛型将C#函数转换为Golang实现

使用泛型将C#函数转换为Golang实现 我想知道在 Go 中创建这个函数的惯用方式是什么。

protected static T WaitForValue<T>(Func<T> act, T expectedVal, int timeout = 15000, int interval = 16)
{
    if (Debugger.IsAttached)
        timeout *= 100;

    var sw = Stopwatch.StartNew();
    do
    {
        try
        {
            var currentVal = act();
            if (expectedVal.Equals(currentVal))
            {
                return currentVal;
            }
            if (sw.ElapsedMilliseconds > timeout)
            {
                return currentVal;
            }
        }
        catch
        {
            if (sw.ElapsedMilliseconds > timeout)
            {
                throw;
            }
        }

        Thread.Sleep(interval);
    } while (true);
}

更多关于使用泛型将C#函数转换为Golang实现的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我不确定是否完全理解这个方法的作用,但这里有一个示例代码,你可以在此基础上进行修改。

package main

import (
	"fmt"
	"time"
)

func WaitForValue[T comparable](act func() T, expectedVal T, timeout int, interval int) T {
	to := int64(timeout)
	startTime := time.Now().Local()
	for {
		currentVal := act()
		if currentVal == expectedVal {
			return currentVal
		}
		t := time.Now()
		elapsed := t.Sub(startTime)
		if int64(elapsed) > to {
			return currentVal
		}
	}
}

func myFunc() string {
	return "Hello, World!"
}

func main() {
	expectadVal := "Hello, World!"
	result := WaitForValue[string](myFunc, expectadVal, 1500, 16)
	fmt.Println(expectadVal, "=", result)
}

希望对你有帮助。

更多关于使用泛型将C#函数转换为Golang实现的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在 Go 中实现类似功能的惯用方式如下:

package main

import (
	"errors"
	"time"
)

func WaitForValue[T comparable](act func() T, expectedVal T, timeoutMs int, intervalMs int) (T, error) {
	if timeoutMs <= 0 {
		timeoutMs = 15000
	}
	if intervalMs <= 0 {
		intervalMs = 16
	}

	timeout := time.Duration(timeoutMs) * time.Millisecond
	interval := time.Duration(intervalMs) * time.Millisecond

	start := time.Now()
	for {
		currentVal := act()
		
		if currentVal == expectedVal {
			return currentVal, nil
		}

		if time.Since(start) > timeout {
			return currentVal, errors.New("timeout reached")
		}

		time.Sleep(interval)
	}
}

如果需要异常处理,可以这样实现:

func WaitForValueWithRetry[T comparable](act func() (T, error), expectedVal T, timeoutMs int, intervalMs int) (T, error) {
	if timeoutMs <= 0 {
		timeoutMs = 15000
	}
	if intervalMs <= 0 {
		intervalMs = 16
	}

	timeout := time.Duration(timeoutMs) * time.Millisecond
	interval := time.Duration(intervalMs) * time.Millisecond

	start := time.Now()
	for {
		currentVal, err := act()
		if err != nil {
			if time.Since(start) > timeout {
				return currentVal, err
			}
			time.Sleep(interval)
			continue
		}

		if currentVal == expectedVal {
			return currentVal, nil
		}

		if time.Since(start) > timeout {
			return currentVal, errors.New("timeout reached")
		}

		time.Sleep(interval)
	}
}

使用示例:

func main() {
	counter := 0
	getValue := func() int {
		counter++
		return counter
	}

	result, err := WaitForValue(getValue, 5, 10000, 100)
	if err != nil {
		println("Error:", err.Error())
	} else {
		println("Result:", result)
	}
}

这个实现使用了 Go 1.18+ 的泛型,通过 comparable 约束确保类型可以进行比较,使用 time 包处理超时和间隔,并通过返回错误值来处理异常情况。

回到顶部