在 Kotlin 中,当我有一个非公共(public)成员和一个调用它的 inline fun 时,会出现编译错误:
Error:(22, 25) Kotlin: Public-API inline function cannot access non-public-API
private fun f(): Unitdefined incom.example
我找到了几种在公共(public) inline fun 中调用我的函数的方法,但哪种方法最好?
假设我有一个 private fun f() { }。那么我找到的选项是:
fun f() { }
只要公开。这是基准解决方案,但如果其他解决方案有很大的缺点,这可能是最好的解决方案。
@PublishedApi 内部函数 f() { }
在 Kotlin 1.1-M04 中引入,注释可以应用于内部成员,使其有效地公开。我注意到的含义是任何库用户仍然可以从 Java 代码中调用它,这就是我不喜欢它的地方。
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") 内联函数 g() { f() }
发现于 the stdlib sources ,此注释在应用于调用函数时似乎抑制了错误。但它的局限性是什么?它只能用于 inline 函数吗?生成的程序在某些情况下会失败吗?我试图用这个技巧从一个内联函数调用一个非内联函数,它奏效了,但看起来很可疑。
@JvmSynthetic @PublishedApi 内部乐趣 f() { }
将第二个解决方案与字节码中的 synthetic 标志结合起来。我不确定这是否是 correct usage of @JvmSynthetic ,但这似乎对 Java 代码隐藏了该函数,从而解决了 @PublishedApi 内部的问题。
那么,这些解决方案中的哪一个是从公共(public)内联函数调用非公共(public)函数的最佳方式?我看不到的每种解决方案的缺点是什么?
最佳答案
@PublishedApi internal 是公开非公共(public) API 以在公共(public)内联函数中使用的预期方式。
那个 @PublishedApi internal 成员实际上变成了公开的,并且它的名称不会被破坏(如果您注意到相反的情况,请提交错误)。
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") 是一种基于抑制错误而缺少 @PublishedApi 的创可贴解决方法,因此不推荐使用。随着 @PublishedApi 的引入,这种抑制将从标准库中清除。
@JvmSynthetic 结合 @PublishedApi 是一种有趣的方法,但它在调试时可能会导致一些问题,尽管我不确定。
关于内联函数无法访问非公共(public) API : @PublishedApi vs @Suppress vs @JvmSynthetic,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41892715/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)