首页 \ 问答 \ 如果没有注释,Rust无法推断类型(Rust cannot infer type without annotation)

如果没有注释,Rust无法推断类型(Rust cannot infer type without annotation)

由于类型错误error[E0283]: type annotations required: cannot resolve _: std::cmp::Eq下面的代码无法编译error[E0283]: type annotations required: cannot resolve _: std::cmp::Eq 。 编译此代码需要什么类型的注释?

此示例代码取自一个更大的程序,其中MyHashGenerator::hash_node()用于散列AST中的节点(类型T与AST节点内部保存的值相关,但不需要定义AST重现类型错误)。

use std::hash::Hash;

pub trait HashGenerator<T: Clone + Eq + Hash + ToString> {
    fn hash(&self, msg: &str) -> u64;  // Hash a string.
    fn hash_node(&self) -> u64;  // Hash an AST node.
}

struct MyHashGenerator {}

impl<T: Clone + Eq + Hash + ToString> HashGenerator<T> for MyHashGenerator {
    fn hash(&self, msg: &str) -> u64 {
        0
    }

    fn hash_node(&self) -> u64 {
        // error[E0283]: type annotations required: cannot resolve `_: std::cmp::Eq`
        self.hash("")
    }
}

游乐场代码。

这个问题类似于这里的问题 ,但尚未得到回答。


The code below cannot compile due to the type error error[E0283]: type annotations required: cannot resolve _: std::cmp::Eq. What type annotation is needed in order to compile this code?

This example code is taken from a much larger program where MyHashGenerator::hash_node() is used to hash nodes in an AST (the type T relates to a value that is held inside AST nodes, but the definition of the AST is not needed to reproduce the type error).

use std::hash::Hash;

pub trait HashGenerator<T: Clone + Eq + Hash + ToString> {
    fn hash(&self, msg: &str) -> u64;  // Hash a string.
    fn hash_node(&self) -> u64;  // Hash an AST node.
}

struct MyHashGenerator {}

impl<T: Clone + Eq + Hash + ToString> HashGenerator<T> for MyHashGenerator {
    fn hash(&self, msg: &str) -> u64 {
        0
    }

    fn hash_node(&self) -> u64 {
        // error[E0283]: type annotations required: cannot resolve `_: std::cmp::Eq`
        self.hash("")
    }
}

Code on Playground.

This question is similar to the one here, which has not been answered.


原文:https://stackoverflow.com/questions/49537809
更新时间:2019-12-13 08:11

最满意答案

问题是MyHashGenerator没有采用类型参数。 所以你做了一个承诺“ 相同的类型MyHashGenerator就足以作为一个哈希生成器,并且无论T如何都会以完全相同的方式运行”。 self.hash("")是对HashGenerator hash调用,但Rust并不一定知道它 HashGenerator实例相同 。 您可以通过以下两种方式之一明确说明此要求。

选项1:显式类型参数

通过明确告诉Rust参数是什么,可以避免这个问题。

fn hash_node(&self) -> u64 {
    HashGenerator::<T>::hash(self, "")
}

现在它知道专门调用<T>实例,这就足够了。

选项2:幻像数据

您可以将MyHashGenerator参数MyHashGenerator具有(未使用的) T参数。

use std::marker::PhantomData

...

struct MyHashGenerator<T> {
    foo: PhantomData<T>
}

然后Rust可以根据self的类型推断出你想要的实例,只要你将实例声明为

impl<T: Clone + Eq + Hash + ToString> HashGenerator<T> for MyHashGenerator<T> {
    ...
}

然后您不必更改hash_size的实现。

就个人而言,我推荐选项1.它不是很漂亮,但它提供了额外的API保证,事实上无论T如何,事情都会以相同的方式工作。 但是,如果您认为MyHashGenerator可能会使用T参数(或者如果现在这样做,并且只是未包含在您的MCVE中),您可以考虑使用选项2来使该依赖关系更加清晰。


The problem is MyHashGenerator doesn't take a type argument. So you're making a promise "The same type MyHashGenerator will suffice as a hash generator and will behave the exact same way regardless of T". self.hash("") is a call to hash on HashGenerator, but Rust doesn't necessarily know that it's the same HashGenerator instance that hash_node was called on. You can make this requirement explicit in one of two ways.

Option 1: Explicit Type Arguments

By explicitly telling Rust what the arguments are, you can avoid this problem.

fn hash_node(&self) -> u64 {
    HashGenerator::<T>::hash(self, "")
}

Now it knows to call specifically the <T> instance, which will suffice.

Option 2: Phantom data

You can parameterize MyHashGenerator to have an (unused) T parameter.

use std::marker::PhantomData

...

struct MyHashGenerator<T> {
    foo: PhantomData<T>
}

Then Rust can infer which instance you want based on the type of self, so long as you declare your instance as

impl<T: Clone + Eq + Hash + ToString> HashGenerator<T> for MyHashGenerator<T> {
    ...
}

Then you don't have to change your implementation of hash_size.

Personally, I recommend Option 1. It's not as pretty, but it provides the additional API guarantee that things will in fact work the same way regardless of T. However, if you think MyHashGenerator might use the T argument later (or if it does now, and that simply wasn't included in your MCVE), you may consider going with Option 2 to make that dependency more clear.

2018-03-28

相关问答

更多

列出条件以在新列表中获得真或假(List condition to get true or false in new list)

只需使用列表理解: lst = [label == "setosa" for label in labels] Just use a list comprehension: lst = [label == "setosa" for label in labels]

测试一个WCF服务应用程序(Testing a WCF Service Application)

没有用于测试您的服务的Web界面。 但是,根据您的服务使用哪些功能,您可能可以使用SDK中包含的WCF测试客户端 。 不幸的是它有很多限制,所以它不适用于所有的服务。 从msdn: 以下是WCF Test Client不支持的功能列表: 类型:Stream,Message,XmlElement,XmlAttribute,XmlNode,实现IXmlSerializable接口的类型,包括相关的XmlSchemaProviderAttribute属性,以及XDocument和XElement类型,

熊猫:基于NaN切片数据框(pandas: slice dataframe based on NaN)

使用函数notnull或反转isnull : print (df[df.prod_id.notnull()]) prod_id prod_ref 0 10.0 ef3920 1 12.0 bovjhd 4 30.0 kbknkn print (df[~df.prod_id.isnull()]) prod_id prod_ref 0 10.0 ef3920 1 12.0 bovjhd 4 30.0 kbknkn

计算在JavaScript中同时按下的键数(Count how many keys are pressed at the same time in JavaScript)

解决问题的一个简单方法是清除用户离开标签时按下的键。 您可以像这样使用window.onblur事件: window.onblur = function () { numKeys = []; }; 演示 。 请注意,此解决方案不会知道您在另一个窗口中按下的键。 (例如,在另一个窗口中按“向上”,然后再次选择此窗口) A simple solution to your problem would be to clear the keys pressed when the user lea

重新打开插件会越来越多地调用函数(Functions get called more and more times with reopening plugin)

每次调用connect ,它都会添加另一个连接 - 即使它是在同一个插槽中。 因此,您需要将连接移出run()方法并将它们放入对话框的setup方法中,以便它们只进行一次。 Every time you call connect, it adds another connection - even if it's to the same slot. So you need to move the connections out of the run() method and put them i

添加库后无法使用gradle编译Android项目(Can't compile Android project with gradle after adding a library)

您无法在Android Studio中的项目中拥有项目。 您只能拥有模块,以便更改您的项目结构,如下所示,以便它符合允许的项目 - 模块级结构。 MyappProject Myapp build.gradle libraries LibrarySubProject1 build.gradle .... settings.gradle build.gradle(Root only one) 现在使用build.gradle文件执行以下操作 1.根级

getElementsByTagName如何获取xml数据(getElementsByTagName how to get xml data)

尝试 document.write(xmlDoc.getElementsByTagName("EPOLeafNode.LastUpdate")[0].childNodes[0].nodeValue); I was able to figure it out as: document.write(x[i].getElementsByTagName("property")[0].childNodes[0].nodeValue); Thank you guys for helping. :)

Android列表视图与按钮(Android listview with buttons)

将所有按钮的focusable属性设置为false,以便您可以单击列表并触摸所有按钮的事件将起作用 set focusable property of all the buttons to false and so that you can click on list and also touch event for all buttons will work

相关文章

更多

最新问答

更多
  • asp.net任意用户信息(asp.net arbitrary user info)
  • 如何使用python计算docx文件中表中行的值(How to count the row's values in tables in docx file by using python)
  • MySQL:用户访问和数据库覆盖(MySQL: User access and DB overwriting)
  • 还有另一种“使用未分配的局部变量”的问题(Yet Another “Use of unassigned local variable 'whatever' ” question)
  • 开源证书颁发机构软件(Open source certificate authority software)
  • Rails中的迭代form_for是在create上添加模型的所有实例(Iteration in Rails form_for is adding all instances of model on create)
  • 如何扩展我的表视图单元格?(How to expand my table view cell?)
  • 如何使用SPARQL区分Thing和无生命对象(How to differentiate between a Thing and an inanimate object with SPARQL)
  • 在IdentityServer中,Client Secrets和Scope Secrets有什么区别?(In IdentityServer, what is the difference between Client Secrets and Scope Secrets?)
  • 如何在具有附加类时重写类(How do I override a class when it has a attached class)
  • 如何使用Git在Azure上部署C#,MVC4应用程序(How to deploy a C#, MVC4 application on Azure using Git)
  • Sitecore 7内容搜索爬网程序根目录之外的索引项(Sitecore 7 Content Search indexing items outside of crawler root)
  • 我应该在线课程使用utf-8编码吗?(Should I use utf-8 encoding for an online course?)
  • 如何在Cucumber-JS步骤定义中使用Node-mysql连接到MySQL?(How to connect to MySQL using Node-mysql in a Cucumber-JS step definition?)
  • 在MVC 4中的google.maps.LatLng(lat,lon)中将JSON字符串值分配给纬度和经度(Assign the JSON string value to Latitude and Longitude in google.maps.LatLng(lat,lon) in MVC 4)
  • awk:通过特定的分隔符删除字符串(awk: remove strings by specific delimiter)
  • 如何测试Vista的应用程序(How to test app for Vista)
  • Elasticsearch聚合器 - 缺失值的工作原理(Elasticsearch aggregators - How missing values work)
  • 绘制datetime.date熊猫(Plot datetime.date pandas)
  • PostgreSQL作为WSO2 EI和APIM + IS的数据源(PostgreSQL as datasource for WSO2 EI and APIM+IS)
  • 如何使用bash在postgres中运行alter table脚本(How to run alter table script in postgres using bash)
  • 可能使用PHP阻止整个美国州访问我的网站?(Might it be possible to block an entire US state from accessing my site, using PHP?)
  • restangular删除并输入错误网:: ERR_NAME_NOT_RESOLVED(restangular remove and put error net::ERR_NAME_NOT_RESOLVED)
  • 常见问题解答的Modx(Revolution)搜索功能(Modx(Revolution) search function for FAQs)
  • Rubymine如何使用远程口译员和Git?(How Does Rubymine Work With Remote Interpreters and Git?)
  • prepareForSegue和PerformSegueWithIdentifier发件人(prepareForSegue and PerformSegueWithIdentifier sender)
  • postgrsql与PowerShell无提示安装问题(postgresql silent installation issue with powershell)
  • 比较两个greps的输出(Comparing output from two greps)
  • 使用.NET RIA Data Services删除Silverlight 3中的数据(Deleting data in Silverlight 3 with .NET RIA Data Services)
  • 此行中AND运算符的含义(meaning of the AND operator in this line)