不带参数不返回任何值的函数的名称是什么?[关闭]


80

在Java 8的java.util.function程序包中,我们有:

  • 功能:接受一个参数,产生一个结果。
  • 消费者:采取一种论点,什么都不做。
  • 供应商:不带任何争议,得出一个结果。
  • ...:其他处理原语,2个参数等的情况...

但是我需要处理“ 不带参数,不产生任何东西 ”的情况。

在中没有任何内容java.util.functionnal

因此,问题是:

不带参数不返回任何值的函数 ”的名称是什么

在Java 8中,其定义为:

@FunctionalInterface
public interface InsertANameHere {
    void execute();
}

执行程序已经存在并具有另一个用途:“ 一个对象,该对象执行已提交的可运行任务 ”。签名不匹配(execute(Runnable):void),甚至都不是一个功能接口

Runnable存在,但它与线程上下文紧密关联:

  • 这个包java.lang不是java.util.function
  • javadoc指出:“ Runnable接口应该由实例打算由线程执行的任何类实现 ”。
  • 名称“ Runnable”建议在线程内运行一些代码。

28
“但是什么都没有,“不做任何争执,什么都不做。” - Runnable吗?
user11153 2015年

11
我认为此时的javadoc Runnable已经过时了,因为Runnable也被ThreadExecutor例如)其他类使用。
SpaceTrucker

13
@superbob这并不意味着Runnables只能是.run()Thread秒。实际上,它们非常准确地用于问题中所述的目的
blgt

5
@superbob那是最初的目的,但是从Java 8开始,它被“改造”为功能接口。所以这就是为什么在java.util.function 包中什么都找不到的原因。
user11153 2015年

5
Semi-Snark:ImpureFuntion,因为它肯定仅依赖于副作用,否则为空。(en.wikipedia.org/wiki/Pure_function#Impure_functions)更严格:强制性(执行某些操作),至少可以匹配void execute()的语义;
克里斯蒂安H

Answers:


71

Java选择这样做的选择是愚蠢的,因为每个Arity都有一个单独的名称。完全不值得模仿。但是,如果出于一致性考虑必须这样做,或者正在编写非常通用的库代码,则Konrad的建议是好的。我可能会Procedure陷入困境。

使用伪功能范式并不意味着正常的命名原则就不会出现。接口应该总是他们什么来命名,不经过一些通用的语法概念。如果将这些函数放入撤消堆栈中,则应将其命名为UndoFunction。如果从GUI事件中调用它们,则应将它们命名为GUIEventHandler。朋友不允许朋友长期使用错误的命名约定。


Procedure也可以 对于上下文,我正在开发一个通用库,该库需要处理这种“结构”。
superbob 2015年

18
我喜欢Procedure我的小事。A Procedure有副作用,A 没有副作用Function。由于您不返回任何值,因此它唯一可以做的就是产生副作用。
Spencer Rathbun 2015年

我可能倾向于将ProcedureRIR<T1,T2>用作void proc(T1, int, T2),也可能将其用于其他类型-可能按需创建其中的大多数,而不是尝试填充每种可能的类型组合。
2015年

1
确实,真正的函数式编程通常不鼓励匈牙利风格的命名。这更多是oo范式的心态而非功能。
slebetman

3
If the functions are placed into an undo stack, they should be named UndoFunction.不过,给函数命名和给它不同的类型之间是有区别的。在实用的风格,你就不会创建UndoFuncton,因为现在你不能将它传递给类型flipcurrycomposefiltermap,等在我看来是真正的原因Java的决定给予函数不同arities不同的名字是愚蠢的。当然,如果您要使用副作用,可以随便叫它;您已经将合成扔到了窗外,并且可以说您也不使用任何函数。
2015年

33

在Java世界中,它称为Runnable。在C#世界中,它称为Action

但是,有一个更好的名称正好适合更大范围的事物。

事情的大局面稍后出现,当您决定除了无参数的void功能接口之外,您还需要具有类似的功能接口,这些功能接口可以接受一个,两个或多个参数,或者返回一个值。发生这种情况时,您将希望所有这些实体的名称都是同构的,并且彼此对应。

因此,在Java中,我有自己的一组称为Procedure的功能接口,定义如下:

public interface Procedure
{
    void invoke();
}

public interface Procedure1<T1>
{
    void invoke( T1 argument1 );
}

...(您得到图片。)

我也有一组类似的称为Functions 的接口,以相似的方式定义,第一个通用参数是返回类型:

public interface Function<R>
{
    R invoke();
}

public interface Function1<R,T1>
{
    R invoke( T1 argument1 );
}

所以,我的意思是,这Procedure是一个非常好的名称,因为它很适合大范围的事物。如果您以后决定使用具有接受参数或返回值的方法的相似功能接口,则会遇到这种情况。

注意:我基本上同意卡尔·比勒费尔特(Karl Bielefeldt)的主张,即“正常的命名原则不应该超出范围”,并且“接口应该几乎总是以其所做的工作来命名,而不是以某种通用的句法思想来命名”。但是请注意,即使他也允许“几乎总是”。有时需要(基本上是匿名的)过程和功能,这就是OP的要求,这就是我要回答的问题。

修订2017-11-10:

您可能会问,为什么Function1<R,T1>而不是Function1<T1,R>?可以使用任何一种方法,但是我偏爱左侧的返回值,因为我喜欢遵循“转换为”(目的地为源)命名约定,而不是“转换为”(源为-destination)约定。(实际上,这比公约更像是一场意外,实际上在某种意义上说,没有人会想到任何想法,因为如果他们给出了任何想法,他们将达成``转换为公约''。 )

我在Joel Spolksy中读过有关“ 使错误的代码看起来错误”的文章,这是一篇很长的文章,我建议全文阅读,但是如果您想直接跳到手头的情况,请搜索“ TypeFromType”,但要给您TL; DR的想法是,myint = intFromStr( mystr )它比更好myint = strToInt( mystr ),因为在第一种情况下,类型的名称接近于关联的值,因此您可以轻松地看到'int'与'int'匹配,并且'str'与'str'匹配。

因此,通过扩展,我倾向于按照事物在代码中的出现顺序对其进行排序。


1
这个解决方案确实非常好,它似乎比Java自己的Supplier,Consumer,BiFunction ...更具防弹能力,因为它只将所有内容归结为两个概念。这让我想起了@Karl Bielefeldt的回答:“ Java选择这样做,每个愚蠢的人都有一个单独的名字 ”。唯一的“缺点”是它不处理原始类型及其组合(有趣的东西,如DoubleToLongFunction,ToLongBiFunction等)。但是原始
元素

是。基本上,一旦开始用基元替换泛型,就意味着您真的在乎性能,因此如果您偏离此处介绍的约定并使用高度自定义的名称来实现高度自定义的性能改进,则可以。
Mike Nakis 2015年

1
如果我可以接受第二个答案,那么我将根据“过程N,功能N”的建议选择您的答案。我仍然支持它。
superbob 2015年

为什么不Function1<T1, R>呢?
ErikE

@ErikE是一个很好的问题,我修改了帖子以回答。
Mike Nakis

18

为什么不Command呢?假设它不接收任何数据并且不返回任何数据,但是假设调用它会产生某种效果(否则实际上是毫无意义的),我想那大概是它唯一可以做的事情-触发一个动作,使某件事发生。

说到这一点,Action.NET中还有一个通用委托。与Java不同,Consumer它可以接受0到16个参数。换句话说,最简单的版本不需要任何内容​​,请参见MSDN

而且,由于名称并不意味着可以“使用”任何东西,因此它似乎也是一个不错的名称选择。


1
Command很好。可以将它与Command模式混淆,但这可能是解决方案。
superbob 2015年

7
Action比我更喜欢Command。命令听起来更像是被接收和评估的东西,而执行操作则有其副作用。
Bergi

7
嗯...怎么可能不是命令模式?您已经完全构建了Command实体!它甚至具有传统命名的execute()方法。0_o”
hijarian

1
不喜欢Action的建议,因为这是一个常见的(也是很好的)Swing接口。命令是合理的。
user949300 2015年

@ user949300,但这取决于上下文-Java是一个广阔的世界,我是一名Android开发人员(现在),并且没有与J2EE相关的特质;)我当然同意,所选的命名约定不应冲突与您的框架使用的那个。
Konrad Morawski
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.