Как я могу задать аргументы в вызове функции JavaScript? (Частичное Функциональное Приложение)

Почти все ответы либо используют Reflections, либо читают файлы классов из файловой системы. Если вы попытаетесь прочитать классы из файловой системы, вы можете получить ошибки при упаковке своего приложения как JAR или другого. Также вы можете не использовать отдельную библиотеку для этой цели.

Вот еще один подход, который является чистой java и не зависит от файловой системы.

import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

public class PackageUtil {

    public static Collection<Class> getClasses(final String pack) throws Exception {
        final StandardJavaFileManager fileManager = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null);
        return StreamSupport.stream(fileManager.list(StandardLocation.CLASS_PATH, pack, Collections.singleton(JavaFileObject.Kind.CLASS), false).spliterator(), false)
                .map(javaFileObject -> {
                    try {
                        final String[] split = javaFileObject.getName()
                                .replace(".class", "")
                                .replace(")", "")
                                .split(Pattern.quote(File.separator));

                        final String fullClassName = pack + "." + split[split.length - 1];
                        return Class.forName(fullClassName);
                    } catch (ClassNotFoundException e) {
                        throw new RuntimeException(e);
                    }

                })
                .collect(Collectors.toCollection(ArrayList::new));
    }
}

Java 8 не является обязательным. Вы можете использовать для циклов вместо потоков. И вы можете проверить это так

public static void main(String[] args) throws Exception {
    final String pack = "java.nio.file"; // Or any other package
    PackageUtil.getClasses(pack).stream().forEach(System.out::println);
}
53
задан Jason Bunting 26 November 2008 в 21:22
поделиться

4 ответа

В первую очередь, Вам нужно частичное - существует различие между частичным и карри - и здесь все, в чем Вы нуждаетесь, без платформы :

function partial(func /*, 0..n args */) {
  var args = Array.prototype.slice.call(arguments, 1);
  return function() {
    var allArguments = args.concat(Array.prototype.slice.call(arguments));
    return func.apply(this, allArguments);
  };
}

Теперь, с помощью примера, можно сделать точно, что Вы после:

partial(out, "hello")("world");
partial(out, "hello", "world")();

// and here is my own extended example
var sayHelloTo = partial(out, "Hello");
sayHelloTo("World");
sayHelloTo("Alex");

Эти partial() функция могла использоваться для реализации, но не приправление карри. Вот кавычка от сообщение в блоге на различии :

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

Hope, которая помогает.

96
ответ дан Community 7 November 2019 в 18:37
поделиться
3
ответ дан wpercy 7 November 2019 в 18:37
поделиться

При использовании Dojo, Вы просто называете dojo.hitch (), который делает почти точно, что Вы хотите. Почти — потому что это может использоваться для упаковки контекста также. Но Ваш пример является первым:

dojo.hitch(out, "hello")("world");
dojo.hitch(out, "hello", "world")();

, А также:

var A = {
  sep: ", ",
  out: function(a, b){ console.log(a + this.sep + b); }
};

// using functions in context    
dojo.hitch(A, A.out, "hello")("world");
dojo.hitch(A, A.out, "hello", "world")();

// using names in context
dojo.hitch(A, "out", "hello")("world");
dojo.hitch(A, "out", "hello", "world")();

dojo.hitch () является частью Основы Dojo, поэтому как только Вы включали dojo.js, это там для Вас.

Другое общее средство доступно в dojox.lang.functional.curry модуле (зарегистрированный в Функциональная забава в JavaScript с Dojo — просто взгляд на эту страницу для "карри"). Конкретно можно хотеть посмотреть на карри (), и неравнодушный ().

карри () накапливает аргументы (как в Вашем примере), но с одним различием: как только арность удовлетворена, что вызывает функцию, возвращая значение. Реализация Вашего примера:

df.curry(out)("hello")("world");
df.curry(out)("hello", "world");

Уведомление, которое последняя строка не имеет" ()" в конце — это называют автоматически.

неравнодушный () позволяет заменять аргументы наугад:

df.partial(out, df.arg, "world")("hello");
2
ответ дан Eugene Lazutkin 7 November 2019 в 18:37
поделиться

** РЕДАКТИРОВАНИЕ: Посмотрите ответ Jason Bunting. Этот ответ на самом деле показывает, что способ ниже среднего объединить в цепочку многочисленный звонит, ни один-вызов с предварительными установками для некоторых аргументов. Если этот ответ на самом деле помогает с подобной проблемой, несомненно, необходимо будет использовать, применяются и звонят, как Jason рекомендует вместо неясного способа использовать оценку, которую я продумал. **

Хорошо... Ваш на самом деле запишет "неопределенный" много в этом..., но это должно быть близко к тому, что Вы хотите:

function out(a, b) {
    document.write(a + " " + b);
}

function getArgString( args, start ) {
    var argStr = "";
    for( var i = start; i < args.length; i++ ) {
        if( argStr != "" ) {
            argStr = argStr + ", ";
        }
        argStr = argStr + "arguments[" + i + "]"
    }
    return argStr;
}

function setter(func) {
    var argStr = getArgString( arguments, 1 );
    eval( "func( " + argStr + ");" );
    var newSettter = function() {
        var argStr = getArgString( arguments, 0 );
        if( argStr == "" ) {
            argStr = "func";
        } else {
            argStr = "func, " + argStr;
        }
        return eval( "setter( " + argStr + ");" );
    }
    return newSettter;
}

setter(out, "hello")("world");
setter(out, "hello", "world")();

я, вероятно, переместил бы код в getArgString в саму функцию метода set, хотя... немного более безопасный, так как я использовал 'оценку

0
ответ дан Illandril 7 November 2019 в 18:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: