sách gpt4 ăn đã đi

đại biểu - Vấn đề mượn trình kiểm tra cho các trình phân tích cú pháp có thể ủy quyền

In lại Tác giả: Walker 123 Thời gian cập nhật: 29-11-2023 08:29:34 28 4
mua khóa gpt4 giày nike

Tôi có một số trình phân tích cú pháp. Có một cấp cao nhất có thể ủy quyền cho người khác.

Bộ phân tích cú phápchúng tôi bắt đầu từ Người đọc Nhận đầu vào của họ (biến). Tôi chỉ muốn một cái Bộ phân tích cú phápĐể có thể phân tích cú pháp cùng một lúc, chỉ cần có một trình phân tích cú pháp Người đọc .

Tôi đã thực hiện điều này bằng cách tạo một enum cho trình phân tích cú pháp cấp cao nhất, có thể là trình đọc hoặc trình phân tích cú pháp đại biểu (có trình đọc). Bằng cách này, nó chỉ có thể được đọc khi không được ủy quyền, đó là điều tôi muốn.

Từ trình phân tích cú pháp cấp cao nhất, tôi cần phải mượn enum này để xác định những việc cần làm và lấy trình phân tích cú pháp trình đọc hoặc đại biểu. Vấn đề là nếu tôi muốn bắt đầu hoặc dừng việc ủy ​​quyền, tôi cần phải di chuyển Người đọcVề. Nhưng tại thời điểm này nó vẫn có thể thay đổi được mượn.

Tôi đã tạo một ví dụ tối thiểu và bao gồm thông tin về thay thế Gợi ý trong các ý kiến. và vòng đời phi từ vựng:

#![tính năng(nll)]
sử dụng std::mem::replace;

cấu trúc Reader {
tôi: u8,
}
impl Reader {
fn tiếp theo(&mut chính nó) -> u8 {
/* một số logic ở đây */
tự.i += 1;
bản thân tôi
}
}

Trình phân tích cú pháp đặc điểm {
fn phân tích(&mut bản thân) -> u8;
}

enum ReaderOrDelegate {
Đọc(Người đọc),
Delegate(AnotherParser), /* Đối tượng đặc điểm trong thực tế, nhưng giữ cho nó đơn giản ở đây. */
}

cấu trúc OneParser {
reader_or_delegate: Người đọc hoặc người đại diện,
}
impl Parser cho OneParser {
fn phân tích(&mut bản thân) -> u8 {
khớp với self.reader_or_delegate {
ReaderOrDelegate::Delegate(tham chiếu mut đại biểu) => {
khớp lệnh delegate.parse() {
0 => {
thay thế(&mut self.reader_or_delegate, ReaderOrDelegate::Read(delegate.consume()));
tự phân tích()
},
x => 2 * x
}
},
ReaderOrDelegate::Read(tham chiếu mut reader) => {
khớp reader.next() {
0 => {
thay thế(&mut self.reader_or_delegate, ReaderOrDelegate::Delegate(AnotherParser { reader }));
tự phân tích()
},
x => 3 * x
}
},
}
}
}

cấu trúc AnotherParser {
người đọc: Người đọc,
}
triển khai AnotherParser {
fn tiêu thụ(bản thân) -> Người đọc {
tự.đọc
}
}
impl Parser cho AnotherParser {
fn phân tích(&mut bản thân) -> u8 {
self.reader.next() * 2
}
}

Với gợi ý bình luận vẫn còn lỗi:

lỗi[E0308]: các loại không khớp
--> src/main.rs:42:106
|
42 | thay thế(&mut self.reader_or_delegate, ReaderOrDelegate::Delegate(AnotherParser { reader }));
| ^^^^^^ mong đợi struct `Reader`, tìm thấy &mut Reader
|
= lưu ý: loại mong đợi `Reader`
tìm thấy loại `&mut Reader`

Tôi tin tôi có thể vượt qua người đọc Giải pháp cho vấn đề này xuất phát từ Người đọc hoặc đại biểuvà sử dụng nó như Rc<>>> trong mỗi trình phân tích cú pháp Nhưng tôi nghĩ sẽ hợp lý hơn nếu đặt nó trong một enum: mỗi lần chỉ có một trình phân tích cú pháp có thể sử dụng trình đọc. Điều này có thể thực hiện được không?

Tôi biết lỗi này có ý nghĩa trong trường hợp này, nhưng tôi cảm thấy ở cấp độ cao, tôi có thể làm được những gì mình muốn. Người đọc Chỉ cần một chủ sở hữu.

biên tập:đối với tôi,thay thế Điều quan trọng là câu hỏi có thể được áp dụng cho trường hợp này bằng cách "lồng" (người đọc đã được cuộc thi đấu Mượn rồi muốn đổi ruộng). Vì vậy, mặc dù nó có thể phù hợp nhưng tôi không nghĩ một câu hỏi khác là đủ để giải quyết vấn đề này. Dù sao thì cũng không dành cho tôi.

Chỉnh sửa 2: Bao gồm các đề xuất nhận xét trong các ví dụ về mã và lỗi.

câu trả lời hay nhất

Hãy xem xét dòng này:

thay thế(&mut self.reader_or_delegate, ReaderOrDelegate::Delegate(AnotherParser { reader }));

bạn cần một cáingười đọcGiá trị, không phải tài liệu tham khảo, xây dựnganotherParser :

lỗi[E0308]: các loại không khớp
--> src/main.rs:42:106
|
42 | thay thế(&mut self.reader_or_delegate, ReaderOrDelegate::Delegate(AnotherParser { reader }));
| ^^^^^^ mong đợi struct `Reader`, tìm thấy &mut Reader
|
= lưu ý: loại mong đợi `Reader`
tìm thấy loại `&mut Reader`

Nhưng không thể có được giá trị như vậy. Nếu chúng ta cố gắng:

ReaderOrDelegate::Đọc(người đọc) => {
khớp reader.next() {
0 => {
thay thế(&mut self.reader_or_delegate, ReaderOrDelegate::Delegate(AnotherParser { reader }));
tự phân tích()
},
x => 3 * x
}
},

Bây giờ chúng tôi đã tìm thấy vấn đề thực sự với thiết kế của bạn:

lỗi[E0507]: không thể di chuyển ra khỏi nội dung đã mượn
--> src/main.rs:39:36
|
39 | ReaderOrDelegate::Đọc(người đọc) => {
| ^^^^^^ không thể di chuyển ra khỏi nội dung đã mượn

phân tíchTham khảo phương phápbản thânĐiều này có nghĩa là tại thời điểm này chúng ta không thể loại bỏ giá trị sở hữu khỏi tài sản được mượn.bản thân .

Cũng lưu ý những lỗi E0507Cũng áp dụng cho dòng này:

thay thế(&mut self.reader_or_delegate, ReaderOrDelegate::Read(delegate.consume()));

bởi vìtiêu thụthử mượn từ đại biểu Di chuyển một giá trị ra khỏi .

Trong mã của bạn, trình biên dịch không hiển thị vấn đề, nhưng nếu bạn nhận xét dòng dường như là vấn đề duy nhất có trong ví dụ của bạn thì đúng là như vậy.

Giải pháp duy nhất tôi có thể sắp xếp mà không gây ra lỗi kiểm tra mượn và không chuyển đổi quá nhiều thiết kế của bạn là dựa trên việc sử dụng bộ đếm tham chiếu Người đọc , được chia sẻ giữa trình phân tích cú pháp cấp cao nhất và trình phân tích cú pháp đại biểu.

RcBạn chỉ có một trình đọc được chia sẻ với trình phân tích cú pháp của mình thông qua con trỏ thông minh.

ĐọcHoặcDelegate Enum chỉ cho biết trình phân tích cú pháp của sự kiện, không còn người đọc nào để di chuyển nữa.

#![tính năng(nll)]
sử dụng std::rc::Rc;

cấu trúc Reader {
tôi: u8,
}

impl Reader {
fn tiếp theo(&mut chính nó) -> u8 {
/* một số logic ở đây */
tự.i += 1;
bản thân tôi
}
}

Trình phân tích cú pháp đặc điểm {
fn phân tích(&mut bản thân) -> u8;
}

enum ReaderOrDelegate {
Đọc,
Đại biểu,
}

cấu trúc OneParser {
reader_or_delegate: Người đọc hoặc người đại diện,
người đọc: Rc,
đại biểu: AnotherParser
}

impl Parser cho OneParser {
fn phân tích(&mut bản thân) -> u8 {
khớp với self.reader_or_delegate {
Người đọc hoặc đại diện::Đại diện => {
khớp với self.delegate.parse() {
0 => {
self.reader_or_delegate = Người đọc hoặc Người ủy quyền::Đọc;
tự phân tích()
},
x => 2 * x
}
},
Người đọc hoặc đại diện::Đọc => {
khớp Rc::get_mut(&mut self.reader).unwrap().next() {
0 => {
self.reader_or_delegate = Người đọc hoặc Người đại diện::Người đại diện;
tự phân tích()
},
x => 3 * x
}
},
}
}
}

cấu trúc AnotherParser {
người đọc: Rc
}

impl Parser cho AnotherParser {
fn phân tích(&mut bản thân) -> u8 {
Rc::get_mut(&mut self.reader).unwrap().next() * 2
}
}

Về các đại biểu - mượn trình kiểm tra cho các trình phân tích cú pháp có thể ủy quyền, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/50535022/

28 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress