第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會有你想問的

證明迭代鍵的 `get` 非空

證明迭代鍵的 `get` 非空

慕尼黑5688855 2023-06-04 10:32:10
我有一個(gè)具有類似地圖功能的接口,但沒有實(shí)現(xiàn) Java 的 Map 接口。地圖接口還實(shí)現(xiàn)了Iterable<Object>;它遍歷地圖的鍵我想this在增強(qiáng)循環(huán)的主體中使用(見下文),但沒有斷言,并用于get檢索迭代鍵的值,并且沒有[ERROR]來自 Checker Framework 的 an 。這完全有可能嗎?您能否提供從哪里開始的指示或可以學(xué)習(xí)的示例?我試著隨意地在這里和那里灑一些@KeyFors,但是由于缺乏完全理解我在做什么,我可能需要一段時(shí)間才能找到正確的位置;-)我知道我們可能會使用“條目迭代器”并避免首先解決這個(gè)問題,但我真的只是想學(xué)習(xí)如何向 Checker Framework 傳授鍵迭代器和方法之間的語義關(guān)系@Nullable get。這是一個(gè)最小的工作示例:import org.checkerframework.checker.nullness.qual.Nullable;interface IMap extends Iterable<Object> {    @Nullable Object get(Object o);    IMap put(Object key, Object value); // immutable put    IMap empty();    default IMap remove(Object key) {       IMap tmp = empty();       for (Object k : this) {           if (!k.equals(key)) {               tmp.put(k, get(k)); // get(k) is always non-null because of the key iterator           }       }       return tmp;    }}class Map implements IMap {   java.util.Map<Object, Object> contents = new java.util.HashMap<>();   public Map() { }   private Map(java.util.Map<Object, Object> contents) {      this.contents = contents;      }   @Override   public @Nullable Object get(Object key) {     return contents.get(key);   }   @Override   public IMap empty() {       return new Map();   }   @Override   public IMap put(Object key, Object value) {      java.util.Map<Object, Object> newContents = new java.util.HashMap<>();      newContents.putAll(contents);      newContents.put(key, value);      return new Map(newContents);   }   @Override   public java.util.Iterator<Object> iterator() {      return contents.keySet().iterator();   }}
查看完整描述

2 回答

?
紅糖糍粑

TA貢獻(xiàn)1815條經(jīng)驗(yàn) 獲得超6個(gè)贊

Nullness Checker 警告您規(guī)范(類型注釋)與代碼本身不一致。


無效性問題

您的代碼的關(guān)鍵問題在這里:


tmp.put(k, get(k))

錯誤信息是:


error: [argument.type.incompatible] incompatible types in argument.

? ? ? ? ? ? ? ?tmp.put(k, get(k)); // get(k) is always non-null because of the key iterator

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?^

? found? ?: @Initialized @Nullable Object

? required: @Initialized @NonNull Object

以下是兩個(gè)不兼容的規(guī)范:

  1. put需要一個(gè)非空的第二個(gè)參數(shù)(回想一下這@NonNull是默認(rèn)值):

???public?IMap?put(Object?key,?Object?value)?{?...?}
  1. get可能隨時(shí)返回 null,而客戶端無法知道返回值何時(shí)可能為非 null:

???@Nullable?Object?get(Object?o);

如果你想聲明一個(gè)方法的返回值在一般情況下是可以為空的,但在某些情況下是非空的,那么你需要使用條件后置條件,比如@EnsuresNonNullIf.

也就是說,Nullness Checker對Map.get.?您的代碼不使用它,因?yàn)槟鷽]有覆蓋的方法java.util.Map.get(盡管它確實(shí)有一個(gè)名為的類Map,與 無關(guān)java.util.Map)。

如果您想要對 進(jìn)行特殊情況處理IMap.get,則可以:

  • 你的課程應(yīng)該擴(kuò)展java.util.Map,或者

  • 您應(yīng)該擴(kuò)展 Nullness Checker 以識別您的班級。

地圖關(guān)鍵問題

你能提供從哪里開始的指導(dǎo)或可以學(xué)習(xí)的例子嗎?

我嘗試隨意地在這里和那里灑一些@KeyFors,但由于缺乏完全理解我在做什么,我可能需要一段時(shí)間才能找到正確的位置;-)

請不要那樣做!那就是痛苦。手冊告訴你不要那樣做;相反,首先思考并編寫描述代碼的規(guī)范。

@KeyFor以下是您可以編寫的三個(gè)注釋:

interface IMap extends Iterable<@KeyFor("this") Object> {

...

? ? default IMap remove(@KeyFor("this") Object key) {

...

? ? @SuppressWarnings("keyfor") // a key for `contents` is a key for this object

? ? public java.util.Iterator<@KeyFor("this") Object> iterator() {

這些注釋分別說明:

  1. 迭代器返回此對象的鍵。

  2. 客戶端必須為此對象傳遞一個(gè)密鑰。

  3. 迭代器返回此對象的鍵。我抑制了警告,因?yàn)榇藢ο蟪洚?dāng)包含對象的包裝器,而且我不記得 Checker Framework 有一種方式說“此對象是一個(gè)字段的包裝器,它的每個(gè)方法都具有相同的屬性作為那個(gè)領(lǐng)域的方法。”

結(jié)果類型檢查沒有問題(此答案第一部分中指出的無效性除外):

import org.checkerframework.checker.nullness.qual.KeyFor;

import org.checkerframework.checker.nullness.qual.NonNull;

import org.checkerframework.checker.nullness.qual.Nullable;


interface IMap extends Iterable<@KeyFor("this") Object> {

? ? @Nullable Object get(Object o);

? ? IMap put(Object key, Object value); // immutable put

? ? IMap empty();


? ? default IMap remove(@KeyFor("this") Object key) {

? ? ? ? IMap tmp = empty();


? ? ? ? for (Object k : this) {

? ? ? ? ? ? if (!k.equals(key)) {

? ? ? ? ? ? ? ? tmp.put(k, get(k)); // get(k) is always non-null because of the key iterator

? ? ? ? ? ? }

? ? ? ? }


? ? ? ? return tmp;

? ? }

}


class Map implements IMap {

? ? java.util.Map<Object, Object> contents = new java.util.HashMap<>();


? ? public Map() {}


? ? private Map(java.util.Map<Object, Object> contents) {

? ? ? ? this.contents = contents;

? ? }


? ? @Override

? ? public @Nullable Object get(Object key) {

? ? ? ? return contents.get(key);

? ? }


? ? @Override

? ? public IMap empty() {

? ? ? ? return new Map();

? ? }


? ? @Override

? ? public IMap put(Object key, Object value) {

? ? ? ? java.util.Map<Object, Object> newContents = new java.util.HashMap<>();

? ? ? ? newContents.putAll(contents);

? ? ? ? newContents.put(key, value);

? ? ? ? return new Map(newContents);

? ? }


? ? @Override

? ? @SuppressWarnings("keyfor") // a key for `contents` is a key for this object

? ? public java.util.Iterator<@KeyFor("this") Object> iterator() {

? ? ? ? return contents.keySet().iterator();

? ? }

}


查看完整回答
反對 回復(fù) 2023-06-04
?
偶然的你

TA貢獻(xiàn)1841條經(jīng)驗(yàn) 獲得超3個(gè)贊

總結(jié)信息性接受的答案:

  1. 無法對給定的代碼示例進(jìn)行注解,使得迭代器和 IMap 的 get 方法之間的語義關(guān)系可以指定給 Checker Framework;

  2. 因此,當(dāng)前報(bào)告的錯誤需要本地非空斷言,重寫代碼以避免鍵迭代器或 SuppressWarning 注釋。

  3. 如果我們想避免這些變通方法,那么有必要對檢查器框架進(jìn)行擴(kuò)展,例如它是如何針對 java.util.Map 進(jìn)行特殊處理的。


查看完整回答
反對 回復(fù) 2023-06-04
  • 2 回答
  • 0 關(guān)注
  • 175 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號