当前位置: 首页 > 知识库问答 >
问题:

Java vararg传递lambda和值

陈哲
2023-03-14

我试图在瓦拉格中统一lambda和简单的值。

public static void Log(String format, Object ... args) {
    final Object[] fmt = new Object[ args.length ];
        for(int i = 0; i < args.length; i++)
            fmt[i] = args[i] instanceof Supplier  ?
                     ( (Supplier) args[i] ).get() :
                     args[i];
    final String s = String.format( format, fmt );
    System.err.println( s );
}

final Supplier
    s = () -> "aaa",
    d = () -> 111;
Log( "%s %d %s %d", "bbb", 222, s, d );    // OK, OUTPUT: bbb 222 aaa 111
Log( "%s %d %s %d", "bbb", 222, () -> "aaa", () -> 111 );  // COMPILE FAIL

错误:方法日志不能应用于给定的类型;找到所需的字符串,对象[]:字符串,字符串,整数,()-

是否可以将 lambda 和值同时传递给 vararg?

共有3个答案

伯英武
2023-03-14

问题是Object不是@FunctionalInterface。也就是说,您可以传递这样一个简单的匿名实例:

Log( "%s %d %s %d", "bbb", 222, new Supplier<String>() {
            @Override
            public String get() {
                return "aaa";
            }
        }); 

如果不想使用将导致编译器警告的未检查强制转换,可以使用此方法。

如果您仍然想要投射lambda,可以这样做:

Log( "%s %d %s %d", "bbb", 222, (Supplier<String>) () -> "aaa");
凌俊语
2023-03-14

对于编译器来说,当你删除它们时,没有办法知道使用了什么类型的函数接口(不像第一个,因为你在变量类型中定义了它)

因此,修复方法是铸造供应商。E、 g.(未测试)

Log( "%s %d %s %d", "bbb", 222, ((Supplier<String>)() -> "aaa"), ((Suplier<Integer>)() -> 111) ); 

希望这指向正确的方向。

盖诚
2023-03-14

问题出在错误信息里

对象不是功能接口

您只能为函数接口(只有一个抽象方法的接口)创建lambda。对象不是接口,它没有任何抽象方法,因此您不能创建这种类型的lambda。你能做的是

Log( "%s %d %s %d", "bbb", 222, (Supplier) () -> "aaa", (Supplier) () -> 111 );  

这样编译器就知道要实现的lambda类型。

相比之下,您可以编写以下内容,这在您的方法中的行为会有所不同。

Log( "%s %d %s %d", "bbb", 222, (Callable) () -> "aaa", (Callable) () -> 111 );  
 类似资料:
  • Go 语言中 值类型 有:int 系列、float 系列、bool、string、数组、结构体 值类型通常在栈中分配存储空间 值类型作为函数参数传递,是拷贝传递 在函数体内修改值类型参数,不会影响到函数外的值 package main import "fmt" func main() { num := 10 change(num) fmt.Println(num) // 10 }

  • 问题内容: 据说在Java方法中,参数是通过值传递的,这对于基元和对象都是正确的,而对象的引用是通过值传递的。为了说明,请考虑以下代码: 能给出相同结果的C ++等价物是什么? 在调用该方法后,使d1的值与该方法内的值相同,即调用方看到修改后的值,那么C ++的等效项是什么? 问题答案: C ++对于值和引用的语义与Java不同。首先,每种类型都有可能通过复制,引用或地址传递(但是,可以通过隐藏复

  • 我试图创建一个集中的日志存储桶,然后使用lambda和AWS-cdk记录所有其他s3存储桶。已创建了集中式日志存储桶,但在使用lambda对其进行写入时出错。这是我的代码:导入boto3 S3=boto3.resource('s3') 注意:除了这个日志传递权限之外,一切都可以正常工作,因为当我通过aws控制台启用它时,它可以正常工作,但是,我需要以编程方式执行它!先谢谢你。

  • 我有这个代码: 为什么我不能修改lambda函数中通过捕获传递的向量? 我得到了这个错误: 11: 21:错误:将“const std::vector”作为“void std:”vector的“this”参数传递 我可以通过引用传递它,但问题是,如果从线程调用lambda,那么它将超出范围,矢量将不再可用。

  • 主要内容:1、值传递,2、引用传递,3、输出传递通过前面的学习我们知道,在调用带有参数的函数时,需要将参数传递给函数。在介绍这几种传递方式之前,我们先来介绍一下形式参数(形参)和实际参数(实参)这两个概念: 形式参数:在定义函数阶段参数列表中定义的参数称之为形式参数,简称形参,可以将它看作变量的名称,它没有具体的值,只是用来接收函数调用时传递过来的数据; 实际参数:在函数被调用时传递给函数的参数称之为实际参数,简称实参,可以将它看作变量的值,用

  • 两者之间有什么区别 引用传递的参数 通过值传递的参数? 你能给我举几个例子吗?