- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
嗨,我有以下this tutorial可以更深入地学习如何处理 rust ,因此我知道这现在可能是正确的处理方法。这是包含所有code进行深入研究的存储库。我有一个全局性的VGA编写器实例,该实例对于数据竞赛而言必须是安全的,因此使用lazy_static
可以对其进行初始化。我想做的是仅当我实际打印字符串时才能够获取锁定,以便在我想打印字符串时而不是在fmt::Write
上实现WrappedWriter
而不是Writer
而不是获得对spin::Mutex
的锁定我想在格式化参数后获得锁。但是,当我将此称为write函数时:
crate::vga_buffer::WRITER.write_fmt(args).unwrap();
我收到以下错误:
Compiling rust_os v0.1.0 (D:\Workspace\Organiztions\home\rust\rust_os)
error[E0055]: reached the recursion limit while auto-dereferencing `vga_buffer::writer::WrappedWriter`
--> src\lib.rs:19:31
|
19 | crate::vga_buffer::WRITER.write_fmt(args).unwrap();
| ^^^^^^^^^ deref recursion limit reached
|
= help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`rust_os`)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0055`.
error: could not compile `rust_os`.
这是
Writer
+
WrappedWriter
的实现
use core::fmt;
use lazy_static::lazy_static;
use volatile::Volatile;
use super::color::*;
use super::screen_character;
use core::ops::{DerefMut, Deref};
// #[allow(dead_code)]
// use crate::serial_print;
// use crate::serial_println;
pub const BUFFER_HEIGHT: usize = 25;
pub const BUFFER_WIDTH: usize = 80;
#[repr(transparent)]
struct Buffer {
chars: [[Volatile<screen_character::ScreenCharacter>; BUFFER_WIDTH]; BUFFER_HEIGHT],
}
pub struct Writer {
column_position: usize,
color_code: ColorCode,
buffer: &'static mut Buffer,
}
impl Writer {
pub fn new(column_position: usize,
color_code: ColorCode) -> Writer {
return Writer {
column_position,
color_code,
buffer: unsafe { &mut *(0xb8000 as *mut Buffer) },
};
}
}
impl Writer {
pub fn write_byte(&mut self, byte: u8) {
match byte {
b'\n' => self.new_line(),
byte => {
if self.column_position >= BUFFER_WIDTH {
self.new_line();
}
let row = BUFFER_HEIGHT - 1;
let col = self.column_position;
let color_code = self.color_code;
self.buffer.chars[row][col].write(screen_character::ScreenCharacter::new(byte, color_code));
self.column_position += 1;
}
}
}
pub fn write_string(&mut self, s: &str) {
for byte in s.bytes() {
match byte {
// printable ASCII byte or newline
0x20..=0x7e | b'\n' => self.write_byte(byte),
// not part of printable ASCII range
_ => self.write_byte(0xfe),
}
}
}
fn new_line(&mut self) {
for row in 1..BUFFER_HEIGHT {
for col in 0..BUFFER_WIDTH {
let current_character = self.buffer.chars[row][col].read();
self.buffer.chars[row - 1][col].write(current_character);
}
}
self.clear_row(BUFFER_HEIGHT - 1);
self.column_position = 0;
}
fn clear_row(&mut self, row_index: usize) {
let blank = screen_character::ScreenCharacter::new(b' ', self.color_code);
for col in 0..BUFFER_WIDTH {
self.buffer.chars[row_index][col].write(blank);
}
}
}
// impl fmt::Write for Writer {
// fn write_str(&mut self, s: &str) -> fmt::Result {
// self.write_string(s);
// Ok(())
// }
// }
struct WrappedWriter {
value: spin::Mutex<Writer>
}
impl fmt::Write for WrappedWriter {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.value.lock().write_string(s);
Ok(())
}
}
impl Deref for WrappedWriter {
type Target = WrappedWriter;
fn deref(&self) -> &Self::Target {
return self;
}
}
impl DerefMut for WrappedWriter {
fn deref_mut(&mut self) -> &mut Self::Target {
return self;
}
}
lazy_static! {
pub static ref WRITER: WrappedWriter = {
let writerInstance = WrappedWriter {
value: spin::Mutex::new(
Writer::new(0, ColorCode::new(Color::Yellow, Color::Black))
)
};
writerInstance
};
}
#[test_case]
fn test_println_output() {
let test_str = "Some test string that fits on a single line";
println!("{}", test_str);
for (char_index, char) in test_str.chars().enumerate() {
let screen_char = WRITER.value.lock().buffer.chars[BUFFER_HEIGHT - 2][char_index].read();
assert_eq!(char::from(screen_char.ascii_character), char);
}
}
之所以实现
Deref
+
DerefMut
,是因为没有它们,我会收到以下错误,但是又一次,我又不知道该如何取消引用,因为从角度来看,我实际上并不需要取消引用,因为
write_fmt
有点自我
error[E0596]: cannot borrow data in a dereference of `vga_buffer::writer::WRITER` as mutable
--> src\lib.rs:19:5
|
19 | crate::vga_buffer::WRITER.write_fmt(args).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
|
= help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `vga_buffer::writer::WRITER`
最佳答案
WrappedWriter
当前对自身进行反引用,对自身进行反引用,对自身进行反引用,依此类推,这就是您达到递归限制的原因。您可能想要通过获取锁使其内部的Writer
解除引用。
关于rust - 如何正确实现Deref + DerefMut?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63204783/
嗨,我有以下this tutorial可以更深入地学习如何处理 rust ,因此我知道这现在可能是正确的处理方法。这是包含所有code进行深入研究的存储库。我有一个全局性的VGA编写器实例,该实例对于
我正在尝试可变地借用一个可变变量。 Deref和DerefMut是为Foo实现的,但是编译失败: use std::ops::{Deref, DerefMut}; struct Foo; impl D
我正在尝试可变地借用一个可变变量。 Deref和DerefMut是为Foo实现的,但是编译失败: use std::ops::{Deref, DerefMut}; struct Foo; impl D
我正在尝试可变地借用一个可变变量。 Deref和DerefMut是为Foo实现的,但是编译失败: use std::ops::{Deref, DerefMut}; struct Foo; impl D
我想在 RefCell 中包装一个 FnMut 闭包,如下所示: fn borrow_mut_closure() { let mut temp = 3i32; let cl = Ref
我是一名优秀的程序员,十分优秀!