使用函数引用在 Kotlin 中重写 Java 代码发生 SAM 类型冲突

2023-12-07

我有一个使用方法引用的示例 Java 代码,我想将其重写为 Kotlin。 Java版本使用方法参考,解决方案简短明了。但另一方面,我无法在 Kotlin 中使用方法引用。我设法编写的唯一版本是下面的版本。这好像是Function3 { s: String, b: Boolean, i: Int -> combine(s, b, i) }可以以更简洁的方式编写(如果可能的话方法参考将是完美的)。

我是 Kotlin 新手,所以我将不胜感激任何线索。

Java

import io.reactivex.Observable;

public class TestJava {

    Observable<String> strings() {
        return Observable.just("test");
    }

    Observable<Boolean> booleans() {
        return Observable.just(true);
    }

    Observable<Integer> integers() {
        return Observable.just(1);
    }

    void test() {
        Observable.combineLatest(strings(), booleans(), integers(),
                this::combine);
    }

    double combine(String s, boolean b, int i) {
        return 1.0;
    }
}

Kotlin

import io.reactivex.Observable
import io.reactivex.functions.Function3

class TestKotlin {

    fun strings(): Observable<String> {
        return Observable.just("test")
    }

    fun booleans(): Observable<Boolean> {
        return Observable.just(true)
    }

    fun integers(): Observable<Int> {
        return Observable.just(1)
    }

    fun test() {
        Observable.combineLatest(strings(), booleans(), integers(),
                Function3 { s: String, b: Boolean, i: Int -> combine(s, b, i) })
    }

    fun combine(s: String, b: Boolean, i: Int): Double {
        return 1.0
    }
}

EDIT

Kotlin 中的以下方法引用会出现错误。

fun test() {
    Observable.combineLatest(strings(), booleans(), integers(), this::combine)
}

fun test() {
    Observable.combineLatest(strings(), booleans(), integers(), TestKotlin::combine)
}

不能使用参数调用以下函数 提供: @CheckReturnValue @SchedulerSupport public final fun mergeLatest(p0: ((Observer) -> Unit)!, p1: ((Observer) -> Unit)!, p2: ((观察者) -> 单位)!, p3: ((???, ???, ???) -> ???)!): 可观察!定义在 io.reactivex.Observable 中 @CheckReturnValue @SchedulerSupport public open fun mergeLatest(p0: ObservableSource!, p1: ObservableSource!, p2: ObservableSource!,p3:io.reactivex.functions.Function3!): 可观察!定义在 io.reactivex.Observable 中 @CheckReturnValue @SchedulerSupport public open fun mergeLatest(p0: Function!, out (???..???)>!, p1: Int, vararg p2: ObservableSource!): 可观察!定义在 io.reactivex.Observable 中

EDIT 2

RxKotlin解决了答案中提到的问题。

import io.reactivex.rxkotlin.Observables

class TestKotlin {

    fun test() {
        Observables.combineLatest(strings(), booleans(), integers(), this::combine)
    }

}

您还可以使用函数引用表达式在 Kotlin 中就像 Java 中的方法引用表达式一样。例如,combine函数参考为KFunction3在 Kotlin 中如下:

val f: kotlin.reflect.KFunction3<String, Boolean, Int, Double> = this::combine

在java中,方法引用表达式可以分配给任何兼容的 功能接口,但你不能分配一个函数引用表达式任何函数类型,即使它们是兼容的, 例如:

val f:io.reactivex.functions.Function3<String,Boolean,Int,Double> =this::combine
//                                                type mismatch error     ---^

事实上,Kotlin 使用SAM 转换转换 lambda/函数引用表达式转化为Java的实现功能接口,这意味着 Kotlin 会执行如下操作:

fun test() = TODO()

val exector:Executor = TODO()

exector.execute(::test)

//::test compile to java code as below:
Runnable task = new Runnable(){
   public void run(){
      test();
   }
};

Whydid 方法引用表达式在 Java 中可以正常工作,但是使用函数引用表达式Kotlin 失败了?

根据上面的内容,你可以看到有很多重载的地方combineLatest中的方法rx-java2。例如,以下两个不能使 Kotlin 使用函数引用表达式正确:

combineLatest(
       ObservableSource<out T1>,
       ObservableSource<out T2>,
       ObservableSource<out T3>, 
       Function3<T1, T2, T3, out R>
)

combineLatest(
       ObservableSource<out T1>,
       ObservableSource<out T2>,
       ObservableSource<out T3>, 
       ObservableSource<out T4>, 
       Function4<T1, T2, T3, T4, out R>
)

正如我所说,Kotlin 使用SAM 转换转换 lambda/函数引用表达式到一个Java功能接口,但它不能分配给Java功能接口直接地。

第4个参数combineLatestKotlin 中的方法,编译器根本无法推断其类型,因为第四个参数类型可以是io.reactivex.functions.Function3 or ObservableSource。因为ObservableSource也是一个Java功能接口.

当你遇见SAM 转换像这样的冲突,你可以使用适配器功能将 lambda 转换为特定的 SAM 类型,例如:

typealias RxFunction3<T1, T2, T3, R> = io.reactivex.functions.Function3<T1,T2,T3,R>

val f: RxFunction3<String, Boolean, Int, Double> = RxFunction3{ s, b, i-> 1.0}

所以你必须在使用 lambda/ 之前使用适应函数引用表达式, 例如:

typealias RxFunction3<T1, T2, T3, R> = io.reactivex.functions.Function3<T1,T2,T3,R>

fun <T1,T2,T3,R> KFunction3<T1,T2,T3,R>.toFunction3(): RxFunction3<T1, T2,T3,R> {
    return RxFunction3 { t1, t2, t3 -> invoke(t1, t2, t3) }
}

Then你可以使用函数引用表达式如下,例如:

Observable.combineLatest(
        strings(),
        booleans(), 
        integers(), 
        //             v--- convert KFunction3 to RxFunction3 explicitly
        this::combine.toFunction3()
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用函数引用在 Kotlin 中重写 Java 代码发生 SAM 类型冲突 的相关文章

  • Java Try Catch Final 没有 Catch 的情况下会阻塞

    我正在审查一些新代码 该程序只有一个 try 和一个 finally 块 既然排除了 catch 块 那么如果 try 块遇到异常或任何可抛出的内容 它如何工作 它直接进入finally块吗 如果 try 块中的任何代码可以引发已检查异常
  • 添加动态数量的监听器(Spring JMS)

    我需要添加多个侦听器 如中所述application properties文件 就像下面这样 InTopics Sample QUT4 Sample T05 Sample T01 Sample JT7 注意 这个数字可以多一些 也可以少一些
  • 如何在spring mvc中从控制器名称+操作名称获取映射的URL?

    是否有现有的解决方案可以从 Spring MVC3 中的 控制器名称 操作名称 获取映射的 URL 例如 asp net mvc 或 Rails 中的 UrlHelper 我觉得非常有用 thx 也许 你想要这样的东西 in your Co
  • 无法使用maven编译java项目

    我正在尝试在 java 16 0 1 上使用 maven 构建 IntelliJ 项目 但它无法编译我的项目 尽管 IntelliJ 能够成功完成 在此之前 我使用maven编译了一个java 15项目 但我决定将所有内容更新到16 0 1
  • Spring安全“记住我”cookie在第一个请求中不可用

    我无法在登录请求后检索 Spring 记住我 cookie 但它在对受保护页面的下一个请求中工作正常 谁能告诉我怎样才能立即得到它 我在登录请求中设置了记住我的 cookie 但在 Spring 重定向回原始 受保护的 url 后无法检索它
  • 在 Anko DSL 中创建自定义 View/ViewGroup 类

    我想创建一个自定义视图 它只是一些 Android 视图的包装 我考虑创建一个自定义 ViewGroup 来管理其子视图的布局 但我不需要这么复杂 我基本上想做的是 class MainActivity verticalLayout tex
  • eclipse中导入项目文件夹图标

    我在 Eclipse 工作区中新导入的 Maven 项目有J and M项目文件夹顶部的图标 项目和包资源管理器 而其他导入的 Maven 项目只有一个J icon 有人可以解释其中的区别吗 该项目有J装饰器被称为 Java 项目和具有M装
  • 如何在 JSP 中导入类?

    我是一个完全的JSP初学者 我正在尝试使用java util List在 JSP 页面中 我需要做什么才能使用除以下类之外的类java lang 使用以下导入语句进行导入java util List 顺便说一句 要导入多个类 请使用以下格式
  • 如何将 android.net.Uri 转换为 java.net.URL? [复制]

    这个问题在这里已经有答案了 有没有办法从Uri to URL 我正在使用的库需要这个 它only接受一个URL但我需要在我的设备上使用图像 如果该方案的Uri is http or https new URL uri toString 应该
  • 具有共享依赖项的多模块项目的 Gradle 配置

    使用 gradle 制作第一个项目 所以我研究了 spring gradle hibernate 项目如何组织 gradle 文件 并开始制作自己的项目 但是 找不到错误 为什么我的配置不起作用 子项目无法解决依赖关系 所以项目树 Root
  • Java 8 中函数式接口的使用

    这是来自的后续问题Java 8 中的 双冒号 运算符 https stackoverflow com questions 20001427 double colon operator in java 8其中 Java 允许您使用以下方式引用
  • 列表应该如何转换为具体的实现?

    假设我正在使用一个我不知道源代码的库 它有一个返回列表的方法 如下所示 public List
  • Java 数组的最大维数

    出于好奇 在 Java 中数组可以有多少维 爪哇language不限制维数 但是JavaVM规范将维度数限制为 255 例如 以下代码将无法编译 class Main public static void main String args
  • 获取给定类文件的目录路径

    我遇到的代码尝试从类本身的 class 文件所在的同一目录中读取一些配置文件 File configFiles new File this getClass getResource getPath listFiles new Filenam
  • Java - 返回值是否会中断循环?

    我正在编写一些基本上遵循以下格式的代码 public static boolean isIncluded E element Node
  • 尝试使用等于“是”或“否”的字符串变量重新启动 do-while 循环

    计算行程距离的非常简单的程序 一周前刚刚开始 我有这个循环用于解决真或假问题 但我希望它适用于简单的 是 或 否 我为此分配的字符串是答案 public class Main public static void main String a
  • 为什么java中的for-each循环中需要声明变量

    for 每个循环的通常形式是这样的 for Foo bar bars bar doThings 但如果我想保留 bar 直到循环结束 我可以not使用 foreach 循环 Foo bar null Syntax error on toke
  • 无法捕获 Spring Batch 的 ItemWriter 中的异常

    我正在编写一个 Spring Batch 流程来将数据集从一个系统迁移到另一个系统 在这种情况下 这就像使用RowMapper实现在传递给查询之前从查询构建对象ItemWriter The ItemWriter称为save我的 DAO 上的
  • JVM:是否可以操作帧堆栈?

    假设我需要执行N同一线程中的任务 这些任务有时可能需要来自外部存储的一些值 我事先不知道哪个任务可能需要这样的值以及何时 获取速度要快得多M价值观是一次性的而不是相同的M值在M查询外部存储 注意我不能指望任务本身进行合作 它们只不过是 ja
  • Java &= 运算符应用 & 或 && 吗?

    Assuming boolean a false 我想知道是否这样做 a b 相当于 a a b logical AND a is false hence b is not evaluated 或者另一方面 这意味着 a a b Bitwi

随机推荐

  • iPhone SDK - 在 Web 视图中打开 UITextView 中的链接

    我在 UITextView 上指定了 dataDetectorTypes 以便在触摸时在 Safari 中打开 URL 是否可以拦截此行为 以便我将 URL 加载到 UIWebView 中 或者我会编写自己的 URL 检测器代码来重新路由它
  • 故障排除:不包含适合入口点的静态“main”方法

    我正在尝试创建一个多类程序 该程序创建学生对象 然后允许您更改其中一个学生对象的未声明专业的值 这是我的代码 StudentApp cs using System using System Collections Generic using
  • XSLT:用 \' 替换单引号

    我正在使用 XSLT 将 XML 转换为 html php 文件 在此 XSLT 中 我用 php 代码替换了一些标签 现在我必须将属性值传递到该 php 代码中 我现在的问题是我必须用反斜杠转义单引号才能使其工作 这可以通过 XSLT 实
  • Shapeless:使用 Coproduct 拥有自己的 HList 约束

    注 从Shapeless 尝试通过类型限制 HList 元素 问题 2 使用余积的自身约束 我真正想做的是使用余积编写一个新的约束 trait CPConstraint L lt HList CP lt Coproduct extends
  • Visual Studio javascript 调试不起作用

    这个博客 从 Visual Studio 在 Microsoft Edge 中调试 JavaScripthttps devblogs microsoft com visualstudio debug javascript in micros
  • CSS:css末尾的问号有什么作用?

    维基百科 css 的示例 content a href https link https background url images external link ltr icon png 2 no repeat scroll right c
  • 如何删除 div 上的边框部分以使左侧导航看起来与主要内容部分无缝衔接?

    我试图删除活动菜单项与右侧内容 div 相遇的左边框 See http d pr i hfRZ 所以看起来活动元素与主要内容 div 的级别相同 如下所示http dribbble com shots 663779 Left navigat
  • swift CGPDF文档解析

    我正在尝试使用 Swift 来解析 PDF 文档的内容 遵循 Apple 的编程指南 其中所有示例都是 ObjC let filepath Users ben Desktop Test pdf let localUrl filepath a
  • 在 Windows 上从命令行下载最新的 Java SE 运行时环境 8

    在 Windows 服务器上 我正在寻找一种可靠的方法来从命令行下载最新的 Java SE 运行时 我的要求是检查系统上是否安装了java 如果没有找到java 我们的MSI安装程序 使用WIX创建 需要连接oracle java下载页面并
  • 较小时 UIScrollView 的中心内容

    我有一个UIImageView里面一个UIScrollView我用它来缩放和滚动 如果滚动视图的图像 内容比滚动视图大 则一切正常 但是 当图像变得小于滚动视图时 它会粘在滚动视图的左上角 我想让它保持居中 就像照片应用程序一样 有关保留内
  • 解码十六进制:这一行的作用是什么 (len & 0x01) != 0

    我正在查看 Apache commons 库中的一段代码 并且想知道这些条件到底有何作用 public static byte decodeHex final char data throws DecoderException final
  • 在特定网络接口 Linux/Unix 上使用 C++ TCP 客户端套接字

    我有以下代码 默认情况下连接到接口 eth0 1G NIC 但我想使用 eth5 10G NIC 进行连接 class TCPClientSocket protected int socket file descriptor public
  • 刷新 angularjs 中的标题页面

    在 angularjs 中登录后我必须刷新 header html 当调用登录时 整个页面将被刷新并初始化标题 但登录后仅加载内容而不是标题 我可以做什么来刷新标题 索引 html div class container holder di
  • 查找所有表列的最小值和最大值

    该查询按预期工作 但速度非常慢 这里有人有提高性能的建议吗 我本质上只是创建一个临时表来存储所有表和列名称 并通过 WHILE 语句循环它们 以使用我想要的详细信息创建到另一个表的动态插入 我最近的一次运行花费了大约 21 分钟 这并不完全
  • 计算Java中HashMap的开销

    假设我在哈希图中存储 1000 个对象 这个哈希图经过扩展 允许我将三维坐标映射到存储在其中的对象 里面的物体有固定的大小 哈希键是一个长整数 我将如何 以数学方式 计算出该结构的可能开销 它是否足够重要 例如 如果内部数据约为 256mb
  • 从 vba 到平面文件的 Unicode 字符串

    我想将 excel vba 宏中的 unicode 字符串存储在 Windows 盒子上的平面文件中 该宏将普通字符串转换为 unicode 表示形式 需要将其存储在文件中并稍后检索 如前所述 您可以使用 Microsoft 脚本运行时 s
  • 根据屏幕尺寸更改列数

    我正在尝试 Bootstrap 我想知道如何根据屏幕尺寸调整列数 我从 Bootstrap CSS 教程中看到了这个 div class row div class col xs 12 col md 8 col xs 12 col md 8
  • ASP.NET Web 项目中的 Razor 视图

    我目前正在研究视图引擎 Razor Views 对我来说变得非常有趣 我正在开发一个 ASP NET 4 0 Web 表单应用程序 我能找到的 Razor 视图示例主要是 MVC 应用程序 是否可以将 Razor 视图集成到 Web 表单应
  • Java - “字符串索引超出范围”异常

    我编写这个小函数只是为了练习 但是抛出了一个异常 字符串索引超出范围 29 我不知道为什么 我知道这不是编写此函数的最佳方法 我可以使用正则表达式吗 这是代码 public String retString String x int j 0
  • 使用函数引用在 Kotlin 中重写 Java 代码发生 SAM 类型冲突

    我有一个使用方法引用的示例 Java 代码 我想将其重写为 Kotlin Java版本使用方法参考 解决方案简短明了 但另一方面 我无法在 Kotlin 中使用方法引用 我设法编写的唯一版本是下面的版本 这好像是Function3 s St