标签: closures

Swift 3可选的转义闭包参数

鉴于:

typealias Action = () -> ()

var action: Action = { }

func doStuff(stuff: String, completion: @escaping Action) {
    print(stuff)
    action = completion
    completion()
}

func doStuffAgain() {
    print("again")
    action()
}

doStuff(stuff: "do stuff") { 
    print("swift 3!")
}

doStuffAgain()
Run Code Online (Sandbox Code Playgroud)

有没有办法制作类型的completion参数(和action)Action?并保持@escaping

更改类型会出现以下错误:

error: @escaping attribute only applies to function types

删除@escaping属性,代码编译并运行,但似乎不正确,因为completion闭包正在逃避函数的范围.

closures function optional swift3

148
推荐指数
5
解决办法
5万
查看次数

词法闭包如何工作?

当我在调查Javascript代码中的词法闭包问题时,我在Python中遇到了这个问题:

flist = []

for i in xrange(3):
    def func(x): return x * i
    flist.append(func)

for f in flist:
    print f(2)
Run Code Online (Sandbox Code Playgroud)

请注意,此示例谨慎避免lambda.它打印"4 4 4",这是令人惊讶的.我期待"0 2 4".

这个等效的Perl代码是正确的:

my @flist = ();

foreach my $i (0 .. 2)
{
    push(@flist, sub {$i * $_[0]});
}

foreach my $f (@flist)
{
    print $f->(2), "\n";
}
Run Code Online (Sandbox Code Playgroud)

打印"0 2 4".

你能解释一下这个区别吗?


更新:

这个问题是不是i是全球性的.这显示相同的行为:

flist = []

def outer():
    for i in xrange(3):
        def inner(x): return x * i …
Run Code Online (Sandbox Code Playgroud)

python closures late-binding lazy-evaluation

144
推荐指数
5
解决办法
3万
查看次数

如何使用Swift @autoclosure

我注意到assert在Swift中编写第一个值时输入为

@autoclosure() -> Bool
Run Code Online (Sandbox Code Playgroud)

用重载方法返回一个通用T值,通过它来测试存在LogicValue protocol.

但严格坚持手头的问题.它似乎想要一个@autoclosure返回一个Bool.

编写一个不带参数并返回Bool的实际闭包不起作用,它要我调用闭包使其编译,如下所示:

assert({() -> Bool in return false}(), "No user has been set", file: __FILE__, line: __LINE__)
Run Code Online (Sandbox Code Playgroud)

然而,简单地通过Bool工作:

assert(false, "No user has been set", file: __FILE__, line: __LINE__)
Run Code Online (Sandbox Code Playgroud)

那么发生了什么?什么是@autoclosure

编辑: @auto_closure已重命名@autoclosure

closures swift

143
推荐指数
3
解决办法
3万
查看次数

我应该如何调用3个函数来一个接一个地执行它们?

如果我需要一个接一个地调用这个函数,

$('#art1').animate({'width':'1000px'},1000);        
$('#art2').animate({'width':'1000px'},1000);        
$('#art3').animate({'width':'1000px'},1000);        
Run Code Online (Sandbox Code Playgroud)

我知道在jQuery中我可以做类似的事情:

$('#art1').animate({'width':'1000px'},1000,'linear',function(){
    $('#art2').animate({'width':'1000px'},1000,'linear',function(){
        $('#art3').animate({'width':'1000px'},1000);        
    });        
});        
Run Code Online (Sandbox Code Playgroud)

但是,我们假设我没有使用jQuery而且我想调用:

some_3secs_function(some_value);        
some_5secs_function(some_value);        
some_8secs_function(some_value);        
Run Code Online (Sandbox Code Playgroud)

我应该如何调用这个函数来执行some_3secs_function,然后在该调用结束后,然后执行some_5secs_function并在该调用结束后再调用some_8secs_function

更新:

这仍然无效:

(function(callback){
    $('#art1').animate({'width':'1000px'},1000);
    callback();
})((function(callback2){
    $('#art2').animate({'width':'1000px'},1000);
    callback2();
})(function(){
    $('#art3').animate({'width':'1000px'},1000);
}));
Run Code Online (Sandbox Code Playgroud)

三个动画同时开始

我的错误在哪里

javascript closures asynchronous callback

138
推荐指数
5
解决办法
24万
查看次数

这个object-lifetime-extends-closure是一个C#编译器错误吗?

当我在C#编译器遇到一些非常奇怪的代码时,我正在回答关于闭包(合法地)延长对象生命周期的可能性的问题(如果重要的话,那就是4.0).

我能找到的最短的repro如下:

  1. 在调用包含类型的静态方法时创建一个捕获局部的lambda .
  2. 将生成的委托引用分配给包含对象的实例字段.

结果:编译器创建一个闭包对象,该对象引用创建lambda的对象,当它没有理由时 - 委托的"内部"目标是静态方法,并且lambda-creation-object的实例成员不需要在委托执行时被(并且没有)触摸.实际上,编译器的行为就像程序员this无缘无故地捕获的那样.

class Foo
{
    private Action _field;

    public void InstanceMethod()
    {
        var capturedVariable = Math.Pow(42, 1);

        _field = () => StaticMethod(capturedVariable);
    }

    private static void StaticMethod(double arg) { }
}
Run Code Online (Sandbox Code Playgroud)

发布版本生成的代码(反编译为'simpler'C#)如下所示:

public void InstanceMethod()
{

    <>c__DisplayClass1 CS$<>8__locals2 = new <>c__DisplayClass1();

    CS$<>8__locals2.<>4__this = this; // What's this doing here?

    CS$<>8__locals2.capturedVariable = Math.Pow(42.0, 1.0);
    this._field = new Action(CS$<>8__locals2.<InstanceMethod>b__0);
}

[CompilerGenerated]
private sealed class …
Run Code Online (Sandbox Code Playgroud)

c# lambda closures memory-leaks object-lifetime

136
推荐指数
2
解决办法
3811
查看次数

将闭包存储为Swift中的变量

在Objective-C中,您可以定义块的输入和输出,存储传递给方法的其中一个块,然后再使用该块:

// in .h

    typedef void (^APLCalibrationProgressHandler)(float percentComplete);
    typedef void (^APLCalibrationCompletionHandler)(NSInteger measuredPower, NSError *error);

    // in .m

    @property (strong) APLCalibrationProgressHandler progressHandler;
    @property (strong) APLCalibrationCompletionHandler completionHandler;

    - (id)initWithRegion:(CLBeaconRegion *)region completionHandler:(APLCalibrationCompletionHandler)handler
    {
        self = [super init];
        if(self)
        {
            ...
            _completionHandler = [handler copy];
            ..
        }

        return self;
}

- (void)performCalibrationWithProgressHandler:(APLCalibrationProgressHandler)handler
{
    ...

            self.progressHandler = [handler copy];

     ...
            dispatch_async(dispatch_get_main_queue(), ^{
                _completionHandler(0, error);
            });
     ...
}
Run Code Online (Sandbox Code Playgroud)

所以我试图在Swift中做等效的事情:

var completionHandler:(Float)->Void={}


init() {
    locationManager = CLLocationManager()
    region = CLBeaconRegion()
    timer = NSTimer()
}

convenience init(region: CLBeaconRegion, …
Run Code Online (Sandbox Code Playgroud)

closures objective-c-blocks swift

132
推荐指数
5
解决办法
9万
查看次数

如何将JS变量的值(而不是引用)传递给函数?

这是我正在尝试运行的简化版本:

for (var i = 0; i < results.length; i++) {
    marker = results[i];
    google.maps.event.addListener(marker, 'click', function() { 
        change_selection(i);
    }); 
}
Run Code Online (Sandbox Code Playgroud)

但我发现每个监听器都使用results.length的值(for循环终止时的值).我如何添加监听器,使得每次使用i时我添加它的值,而不是对i的引用?

javascript closures listener pass-by-reference pass-by-value

116
推荐指数
3
解决办法
4万
查看次数

如何在Playground中运行异步回调

许多Cocoa和CocoaTouch方法都有完成回调,实现为Objective-C中的块和Swift中的闭包.但是,在Playground中尝试这些时,永远不会调用完成.例如:

// Playground - noun: a place where people can play

import Cocoa
import XCPlayground

let url = NSURL(string: "http://stackoverflow.com")
let request = NSURLRequest(URL: url)

NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.currentQueue() {
response, maybeData, error in

    // This block never gets called?
    if let data = maybeData {
        let contents = NSString(data:data, encoding:NSUTF8StringEncoding)
        println(contents)
    } else {
        println(error.localizedDescription)
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以在我的Playground时间轴中看到控制台输出,但是println我的完成块永远不会被调用...

closures asynchronous callback swift swift-playground

116
推荐指数
7
解决办法
3万
查看次数

Python 2.x中的非本地关键字

我正在尝试在Python 2.6中实现一个闭包,我需要访问一个非局部变量,但似乎这个关键字在python 2.x中不可用.如何在这些版本的python中访问闭包中的非局部变量?

python closures python-2.x python-nonlocal

112
推荐指数
6
解决办法
4万
查看次数

关闭使用非转义参数可能允许它逃脱

我有一个协议:

enum DataFetchResult {
    case success(data: Data)
    case failure
}

protocol DataServiceType {
    func fetchData(location: String, completion: (DataFetchResult) -> (Void))
    func cachedData(location: String) -> Data?
}
Run Code Online (Sandbox Code Playgroud)

通过示例实现:

    /// An implementation of DataServiceType protocol returning predefined results using arbitrary queue for asynchronyous mechanisms.
    /// Dedicated to be used in various tests (Unit Tests).
    class DataMockService: DataServiceType {

        var result      : DataFetchResult
        var async       : Bool = true
        var queue       : DispatchQueue = DispatchQueue.global(qos: .background)
        var cachedData  : Data? = nil

        init(result …
Run Code Online (Sandbox Code Playgroud)

closures swift swift3 xcode8-beta6

108
推荐指数
2
解决办法
5万
查看次数