"Закрытие-это объекты бедного человека и наоборот" - что это значит?


замыкания-это объекты бедняка и наоборот.

Я видел это заявление atмногомест в интернете (в том числе), но я не совсем понимаю, что значит. Может кто-нибудь объяснить, что именно это значит?

если возможно, пожалуйста, включите примеры в свой ответ.

6 52

6 ответов:

дело в том, что замыкания и объекты выполняют одну и ту же цель: инкапсуляцию данных и/или функциональности в одном логическом блоке.

например, вы можете создать класс Python, который представляет собаку следующим образом:

class Dog(object):
    def __init__(self):
        self.breed = "Beagle"
        self.height = 12
        self.weight = 15
        self.age = 1
    def feed(self, amount):
        self.weight += amount / 5.0
    def grow(self):
        self.weight += 2
        self.height += .25
    def bark(self):
        print "Bark!"

и затем я создаю экземпляр класса как объект

>>> Shaggy = Dog()

лохматый объект имеет встроенные данные и функциональность. Когда я звоню Shaggy.feed(5), он набирает фунт. Этот фунт хранится в переменной, которая хранится как атрибут объекта, что более или менее означает, что он находится во внутренней области объектов.

если бы я кодировал какой-то Javascript, я бы сделал что-то подобное:

var Shaggy = function() {
    var breed = "Beagle";
    var height = 12;
    var weight = 15;
    var age = 1;
    return {
        feed : function(){
            weight += amount / 5.0;
        },
        grow : function(){
            weight += 2;
            height += .25;
        },
        bark : function(){
            window.alert("Bark!");
        },
        stats : function(){
            window.alert(breed "," height "," weight "," age);
        }
    }
}();

здесь вместо создания области внутри объекта я создал область внутри функции, а затем вызвал эту функцию. Функция возвращает объект JavaScript, состоящий из некоторых функций. Поскольку эти функции обращаются к данным, выделенным в локальной области, память не восстанавливается, что позволяет вам продолжайте использовать их через интерфейс, предусмотренный закрытием.

объекты-это замыкания для бедных.

Рассмотрим Java. Java-это объектно-ориентированный язык программирования без поддержки уровня языка для реальных лексических замыканий. В качестве обходного пути Java-программисты используют анонимные внутренние классы, которые могут закрываться над переменными, доступными в лексической области (при условии, что они final). В этом смысле объекты-это замыкания для бедных.

закрытие объектов бедного человека.

рассмотреть Хаскель. Haskell-это функциональный язык без поддержки уровня языка для реальных объектов. Однако они могут быть смоделированы с помощью замыканий, как описано в этой отличная бумага Олега Киселева и Ральф Lammel. В этом смысле закрытие-это объекты бедного человека.


мораль этой истории такова замыкания и объекты-это идеи, которые выражаются в терминах друг друга, и ни одна из них не является более фундаментальной, чем другая. Это все, что есть в рассматриваемом заявлении.

в философии это называется в зависимости от модели реализма.

объект, в самом простом виде, это просто набор состояний и функций, которые работают в этом состоянии. Закрытие - это также набор состояний и функция, которая работает с этим состоянием.

допустим, я вызываю функцию, которая принимает обратный вызов. В этом обратном вызове мне нужно работать с некоторым состоянием, известным до вызова функции. Я могу создать объект, который воплощает это состояние ("поля") и содержит функцию-член ("метод"), которая выполняет обратный вызов. Или, я мог бы взять быстрый и легкий ("бедный человек") маршрут и создать закрытие.

объект:

class CallbackState{
    object state;

    public CallbackState(object state){this.state = state;}

    public void Callback(){
        // do something with state
    }
}

void Foo(){
    object state = GenerateState();
    CallbackState callback = new CallbackState(state);
    PerformOperation(callback.Callback);
}

это псевдо-C#, но похож по концепции на другие языки OO. Как вы можете видеть,в классе обратного вызова для управления состоянием используется довольно много шаблонов. Это было бы намного проще, используя закрытие:

void Foo(){
    object state = GenerateState();
    PerformOperation(()=>{/*do something with state*/});
}

это лямбда (опять же, в синтаксисе C#, но концепция аналогична в других языках, которые поддерживают замыкания), что дает нам все возможности класса, без необходимости писать, использовать и поддерживать отдельный класс.

вы также услышите вывод:"объекты-это закрытие бедного человека". Если я не могу или не буду пользоваться закрытиями, то я вынужден делать свою работу с помощью объектов, как в моем первом примере. Хотя объекты обеспечивают большую функциональность, закрытие часто является лучшим выбором, где закрытие будет работать, по уже указанным причинам.

следовательно, бедный человек без предметов может часто сделайте работу с закрытиями, и бедный человек без закрытия может сделать работу с помощью объектов. Богатый человек имеет и то и другое и использует правильное для каждой работы.

отредактировано: название вопроса не включает "наоборот", поэтому я постараюсь не предполагать намерения спрашивающего.

два общих лагеря являются функциональными и императивными языками. Оба являются инструментами, которые могут выполнять аналогичные задачи по-разному с различными наборами проблем.

закрытие объектов бедного человека.

объекты-это замыкания для бедных.

индивидуально, каждое заявление обычно означает у автора есть некоторое предубеждение, так или иначе, обычно коренящееся в их комфорте с одним языком или классом языка против дискомфорта с другим. Если нет предвзятости, они могут быть ограничены одной средой или другой. Авторы, которых я читал, говорят, что такие вещи обычно являются фанатиками, пуристами или языковыми религиозными типами. Я избегаю языка религиозных типов, если это возможно.

закрытие объектов бедного человека. Объекты-это замыкания для бедных.

автор из этого есть "прагматик" и тоже довольно умный. Это означает, что автор ценит обе точки зрения и ценит, что они концептуально являются одним и тем же. Это мой тип человека.

"объекты-это закрытие бедного человека" - это не просто утверждение некоторой теоретической эквивалентности-это обычная идиома Java. Очень часто анонимные классы используются для обертывания функции, которая фиксирует текущее состояние. Вот как это используется:

public void foo() {
    final String message = "Hey ma, I'm closed over!";
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            System.out.println(message);
        }
    });
}

Это даже очень похоже на эквивалентный код, использующий закрытие на другом языке. Например, используя блоки Objective-C (поскольку Objective-C достаточно похож на Java):

void foo() {
    NSString *message = @"Hey ma, I'm closed over!";
    [[NSOperationQueue currentQueue] addOperationWithBlock:^{
        printf("%s\n", [message UTF8String]);
    }];
}

единственный реальный разница в том, что функциональность завернута в new Runnable() анонимный экземпляр класса в Java-версии.

просто столько сахара, сколько затворы скрывают анонимные предметы под своими юбками.