当前位置: 首页 > 面试题库 >

如何获得对延迟功能的引用?

赵禄
2023-03-14
问题内容

本文指出:“ defer语句将函数调用推送到列表上。”
我想知道是否可以从程序的另一个位置访问该列表中的元素,然后调用它们?我可以多次调用它们吗?我假设我对具有延迟行为(如果有帮助)的函数进行了引用。

因此,这是我想做的简短示例:

func main {
    doStuff = func() {
        // open database connections
        // write temporary files
        // etc...

        defer func() {
            // close database connections
            // delete temporary files
            // etc...
        }()
    }

    AwesomeApplication(doStuff)
}

func AwesomeApplication(doStuff func()) {
    // Now, can I get a reference to the defer function within `doStuff`?
    // No, I can't just define the defer function somewhere an pass it
    // with `doStuff`.  Think of this as a curiosity I want to satisfy,
    // not a real use case.
}

问题答案:

defer调用存储的“列表” 完全是特定于实现的,因此您 没有可靠的方式访问此列表
。1,2个为*
G编译器家族中的实现细节(虽然有点老),可以发现在拉斯考克斯的研究博客。

延迟函数与当前goroutine(g->Defer)和当前堆栈指针标识的(对于*
g系列)相关联。如果当前堆栈帧与存储在最顶部Defer条目中的堆栈帧匹配,则调用此函数。

了解了这一点它 可以访问的使用CGO延迟功能列表。你得知道

  • 当前的堆栈指针
  • 函数的地址
  • 当前的goroutine

但是,我不建议使用此功能。您描述的用例的一般解决方案是具有以下功能:

func setupRoutines() (setUp, tearDown func()) {
    // store db connection object and such

    return func() { /* connect db and such */ }, func() { /* close db and such */ }
}

然后tearDown,您可以在代码中共享该函数,该函数将使用调用defer。这样,您仍然可以拥有所有数据库连接以及此类本地连接的好处,但是您可以共享初始化/断开连接功能。

小提琴玩

如果您真的想unsafe和C 一起玩,可以将以下代码用作模板。

检查/运行时.c:

// +build gc
#include <runtime.h>

void ·FirstDeferred(void* foo) {
    foo = g->defer->fn;

    FLUSH(&foo);
}

inspect / inspect.go

package inspect

import "unsafe"

func FirstDeferred() unsafe.Pointer

defer.go

package main

import "defer/inspect"

func f(a, b int) {
    println("deferred f(", a, b, ")")
}

func main() {
    defer f(1, 2)
    println( inspect.FirstDeferred() )
}

该代码(基于this)使您可以访问当前的go例程(g),从而可以访问其defer属性。因此,您应该能够访问该函数的指针并将其包装在go中FuncVal并返回它。



 类似资料:
  • 问题内容: 我没有代码示例或任何内容,因为我不知道该怎么做,但是有人可以告诉我如何在一定时间内迅速延迟功能吗? 问题答案: 您可以使用GCD(在示例中,延迟10秒): 迅捷2 Swift 3和Swift 4

  • 问题内容: 使用Hibernate和lazy = true模式从数据库加载对象列表时遇到了一些麻烦。希望有人可以在这里帮助我。 我这里有一个称为UserAccount的简单类,它看起来像这样: 我正在通过以下映射文件在Hibernate中映射此类: 如您所见,在bag映射元素中,lazy设置为“ true”。 将数据保存到数据库可以正常工作: 通过调用也可以加载(请参见下面的代码): 问题只是:当

  • 问题内容: 这是我的情况: 我有一个包含用户列表的页面。我通过Web界面创建一个新用户,并将其保存到服务器。服务器在elasticsearch中为文档建立索引并成功返回。然后,我被重定向到不包含新用户的列表页面,因为它可能需要1秒钟的时间才能使文档在Elasticsearch中可供搜索 elasticsearch中的近实时搜索。 elasticsearch指南说您可以手动刷新索引,但说在生产中不要

  • 问题内容: 如何在MySQL中的此表上做滞后处理以打印引号中的差异,例如: 问题答案: 这是我最喜欢的MySQL hack。 这是模拟滞后函数的方式: 保存上一行报价的值。对于第一行,@ quot是-1。 保留当前行的报价的值。 笔记: 子句在这里很重要,就像在常规窗口函数中一样。 您可能还想使用lag 来确保计算相同引号的差异。 您也可以以相同的方式实现行计数器 与该方案相比,与使用聚合函数,存

  • 问题内容: 我正在尝试用Java做某事,而我需要一些东西在while循环中等待/延迟几秒钟。 我想构建一个步进音序器,并且对Java还是陌生的。有什么建议么? 问题答案: If you want to pause then use java.util.concurrent.TimeUnit: TimeUnit.SECONDS.sleep(1); TimeUnit.MINUTES.sleep(1);

  • 问题内容: 是否有显示大图像并允许用户放大和缩小和平移图像的通用方法? 到目前为止,我发现了两种方法: 覆盖ImageView,对于这样一个常见问题似乎有点过多。 使用网络视图,但对整体布局的控制较少等。 问题答案: 更新 我刚刚给TouchImageView进行了新的更新。现在,除了“平移”和“缩放”缩放外,还包括“双击缩放”和“缩放”。下面的代码是非常过时。您可以签出github项目以获取最新