是否有可能解构方法的`self`参数?

时间:2017-04-25 06:23:41

标签: rust pattern-matching

我试图找到一种方法来解构方法的self参数。根据{{​​3}}:

  

在今天的会议上,我们有一个不同的计划,使自我论证变得无法构建。使用通用函数调用语法(UFCS#11938),静态方法和实例方法之间不会有任何区别 - 它们都是相关的函数'。此时,任何第一个参数的函数都是自我类型,可以使用方法语法调用,而self&self&mut self只是{{1}的糖通过不使用自糖,可以正常地对self参数进行解构。

我编写了以下代码,但它没有像我预期的那样工作,因为所有三个打印函数都可以用作方法。

self: &Self

struct Vector { x: i32, y: i32, z: i32, } impl Vector { fn print1(self: &Self) { println!("{} {} {}", self.x, self.y, self.z); } // destructure self argument fn print2(&Vector{x, y, z}: &Self) { println!("{} {} {}", x, y, z); } // use another name for the first argument fn print3(this: &Self) { println!("{} {} {}", this.x, this.y, this.z); } } fn main() { let v = Vector{x: 1, y: 2, z: 3}; Vector::print1(&v); // work v.print1(); // work Vector::print2(&v); // work v.print2(); // not work Vector::print3(&v); // work v.print3(); // not work } 仅用于测试是否可以使用print3()以外的名称作为方法的第一个参数。

它给出了这个编译错误:

self

似乎error: no method named `print2` found for type `Vector` in the current scope --> 1.rs:27:7 | 27 | v.print2(); // not work | ^^^^^^ | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: candidate #1 is defined in an impl for the type `Vector` --> 1.rs:12:5 | 12 | fn print2(&Vector{x, y, z}: &Self) { | _____^ starting here... 13 | | println!("{} {} {}", x, y, z); 14 | | } | |_____^ ...ending here error: no method named `print3` found for type `Vector` in the current scope --> 1.rs:29:7 | 29 | v.print3(); // not work | ^^^^^^ | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: candidate #1 is defined in an impl for the type `Vector` --> 1.rs:16:5 | 16 | fn print3(this: &Self) { | _____^ starting here... 17 | | println!("{} {} {}", this.x, this.y, this.z); 18 | | } | |_____^ ...ending here print2()未被识别为print3()的方法。

  1. 如何解构方法的Vector参数?
  2. 根据评论,名称self只是糖。这是否意味着self以外的名称可用于方法的第一个参数?

2 个答案:

答案 0 :(得分:9)

这最初是为了通过通用函数调用实现的,但是向后兼容,因为这意味着var ItemViewModel1 = function (data) { var self = this; self.PAR1 = ko.observable(data.PAR1) self.PAR2 = ko.observable(data.PAR2) self.PAR3 = ko.observable(data.PAR3) self.PAR4 = ko.observable(data.PAR4) // … etc } var MasterViewModel1 = function (data) { var self = this; ReportBaseViewModel.call(self) } var ReportBaseViewModel = function () { var self = this; /* commonly used vars */ self.report = ko.observable(); self.searchedCallBackFunction = ko.observable(); self.items = ko.observableArray(); self.selecteditem = ko.observable(); self.selectedPerson = ko.observable(); /* method: print */ self.PrintEventHandler = function (data) { window.print(); }; /* method: add items to array */ self.AddItems = function (data) { var newitems = ko.utils.arrayMap(data, function (item) { c = new window[self.itemname](item); return c; }); self.items(newitems); }; /* eventhandler: select one item */ self.SelectEventHandler = function (item) { selecteditem(item); }; self.GetReport = function (selectedPerson, viewContainer, url, itemName) { self.selectedPerson(selectedPerson); self.itemname = itemName; var jqxhr = $.ajax({ url: url, type: "GET" }).done(function (data, textStatus, jqXHR) { if (data != null) { self.AddItems(data); $('#' + viewContainer).show(); document.getElementById(viewContainer).scrollIntoView(); } }).fail(function (jqXHR, textStatus, errorThrown) { console.log('fail' + JSON.stringify(jqXHR)); toastr.options = { "closeButton": true, "debug": false, "newestOnTop": false, "progressBar": false, "positionClass": "toast-top-right", "preventDuplicates": false, "onclick": null, "showDuration": "0", "hideDuration": "1000", "timeOut": "0", "extendedTimeOut": "0", "showEasing": "swing", "hideEasing": "linear", "showMethod": "fadeIn", "hideMethod": "fadeOut" }; toastr["error"]("ERROR"); }).always(function (jqXHR, textStatus, errorString) { if (typeof self.searchedCallBackFunction() === 'function') { self.searchedCallBackFunction(); } }); } } 突然等同于fn foo(bar: &Self),这可能会因新的问题而中断方法调用方法突然出现。

this github issue comment

中的完整理由

您可以在函数体中使用fn foo(self: &Self)绑定对显式self参数进行解构:

let

答案 1 :(得分:0)

  impl Vector {        
    fn print(&self) {
      // destructure self argument
      let Vector { x, y, z } = &self;
      println!("{} {} {}", x, y, z);
    }
  }