最近,我正在使用kotlin中的列表,并有以下代码段:
a = listOf(1, 2, 3, 4)
println(a[-2])
当然这会导致IndexOutOfBoundsException
所以我认为扩展此功能会很好。所以我认为可以覆盖get
类中的List
运算符:
operator fun <T> List<T>.get(index: Int): T =
// Here this should call the non-overridden version of
// get.
get(index % size)
我理解扩展只是静态方法,因此不能被覆盖,但有没有办法可以实现这样的东西?
当然你可以创建另一个功能
fun <T> List<T>.safeGet(index: Int): T = get(index % size)
但我想知道是否还有其他方式。
(我知道index % size
是一种非常天真的方式来做我想做的事情,但它不是我的问题的焦点,并使代码更小。) < / p>
修改
当我写这个问题时,我认为%
运算符会在右侧为正数时返回正数 - 就像在python中一样。我在这里保留原始问题只是为了保持一致。
答案 0 :(得分:2)
你正在尝试一些不可能的事情,因为扩展程序总是被成员遮蔽,即使@JvmName
也无法拯救你。
解决方法:使用您的第二个解决方案,或添加一个丑陋的Unit
参数(看起来像a[x, Unit]
),但可以与自己的get
方法一起存在。
另一种解决方案:创建自己的List
实施(推荐)。
答案 1 :(得分:2)
由于get
已经在List
中定义了get
运算符,因此您无法重新定义Int
(带有一个invoke
参数)。
但是,您可以覆盖List
中未定义的fun main(args: Array<String>) {
val a = listOf(1, 2, 3, 4)
println(a(-2))
}
// If `index` is negative, `index % size` will be non-positive by the definition of `rem` operator.
operator fun <T> List<T>.invoke(index: Int): T = if (index >= 0) get(index % size) else get((-index) % (-size))
运算符。
List
虽然我认为使用适当的名称为(positive value) % (negative value)
创建新的扩展方法将是更好的选择。
作为旁注,(negative value) % (positive value)
为非负数,%
为非正数。
在以下示例中,Kotlin中的rem
对应于Haskell中的public class Startup: IStartup
{
protected IServiceProvider _provider;
private readonly IConfiguration _configuration;
public Startup(IConfiguration configuration) => _configuration = configuration;
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.Configure<MvcOptions>(options => options.Filters.Add(new RequireHttpsAttribute()));
SetUpDataBase(services);
services.AddMvc();
services
.AddIdentityCore<User>(null)
.AddDefaultTokenProviders();
return services.BuildServiceProvider();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
var options = new RewriteOptions().AddRedirectToHttps();
app.UseRewriter(options);
app.UseAuthentication();
app.UseMvc();
using(var scope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = scope.ServiceProvider.GetService<DatabaseContext>();
EnsureDatabaseCreated(context);
}
}
protected virtual void SetUpDataBase(IServiceCollection services) => services.AddDbContext(_configuration);
protected virtual void EnsureDatabaseCreated(DatabaseContext dbContext)
{
dbContext.Database.Migrate();
}
}
:https://stackoverflow.com/a/28027235/869330