Is it necessary to add code to avoid casting when interface alone is no longer sufficient
// ===== library code: =====
trait Sate // Or in C++ imagine this is a class containing only pure virtuals.
fn ready(&mut self, ..);
fn terminate(&mut self, ..);
fn timeout(&mut self, .. );
fn ....; // a few more functions
fn as_any(&mut self) -> &mut Any; // for downcasting in Rust; not necessary in C++
states: HashMap<u32, Rc<RefCell<State>>>; // Or in C++ just a map of numbers to shared-ptr of State
fn event_loop_on_some_trigger(trigger_for: u32, trigger: Blah)
let state = states[trigger_for];
if trigger == for_timeout state.borrow_mut().timeout(...)
else if trigger = for_readiness state.borrow_mut().timeout(...)
...
//==== User Code: ====
struct Type0 ...
impl State for Type0 /* provide concrete impls */ // In C++ this would be inheritance for Type0
struct Type1 ...
impl State for Type1 /* provide concrete impls */ // In C++ this would be inheritance for Type1
// ... etc.
I was using this library and everything was working fine. But now there are a few types that have to do
some specific work which is beyond what's there in the State
trait above. So i gradually seem
to be running into the "Expressions Problem" in design. I don't control the library providing
the trait and the event-loop and even if i did i wouldn't have added 2 or 3 extra functions
there as it does not feel right since it's going to be used only for some concrete types and
that too occassionally.
What i have additionally is a Map in the user code like HashMap<u32, SomeDetail>
which
corresponds to the map in the event-loop thread stack above. So if i need to perform a special
operation on one of the types i can get the u32
value for the state (by analysing the SomeDetail
or whatever), get the state from the map in the event-loop and downcast it to the type to call
one of the special functions.
At this point in C++ i would probably have used static_cast<>
as I'm sure what type it is
(unless there's something wrong in the bookeeping of the id's or it's allocation which would be
a logic error in the program). In Rust i'm forced to use downcast_mut
(dynamic_cast
in C++),
which I'm OK with (so far I've never got any runtime error from it, showing that the logic is
sound and static_cast
were it available in safe-rust would have worked too).
Now my question is that I read that casting is bad design etc. So I was thinking what could I
have done differently here. One idea was to store the weak (or strong if we don't care) references in the
map that i have in my user code. So while the event loop uses the map it has to fire some
function for the State
, I would use my map to get the concrete type out whenever I want it
and invoke function on it. However since my code is outside the eventloop thread I would have
to slap a Mutex on the states, which is useless in 99% of the time as most of the time it's the
eventloop invoking it and types doing what they are coded to do.
- Should i keep a few maps of (reference to) concrete types the
special functionality on which i want to call occasionally and
slap a mutex there ? - Just do a dynamic_cast in those cases and this is justifiable ?
- Eventloop should have been templatised giving an opportunity for the user to store some state in the eventloop thread stack and deal with it. In this case I would store a few of my maps of
<u32, ConcreteTypeReferences>
so that I can post the request to the event-loop in rare cases I want to interact with the concrete-types and they can continue living without mutex or atomic-referece-counted objects (in Rust Rc is non-atomic-ref-counted smart-ptr, I don't know if there's an equivalent in C++)
The last option and also partly the 1st one requires I have access to that code - so more of a wish-list but just wanting to know what would have been the suggestion if that were the case. In absence of that (2) dynamic_cast
seems the only viable solution ?
design-patterns rust
add a comment |
// ===== library code: =====
trait Sate // Or in C++ imagine this is a class containing only pure virtuals.
fn ready(&mut self, ..);
fn terminate(&mut self, ..);
fn timeout(&mut self, .. );
fn ....; // a few more functions
fn as_any(&mut self) -> &mut Any; // for downcasting in Rust; not necessary in C++
states: HashMap<u32, Rc<RefCell<State>>>; // Or in C++ just a map of numbers to shared-ptr of State
fn event_loop_on_some_trigger(trigger_for: u32, trigger: Blah)
let state = states[trigger_for];
if trigger == for_timeout state.borrow_mut().timeout(...)
else if trigger = for_readiness state.borrow_mut().timeout(...)
...
//==== User Code: ====
struct Type0 ...
impl State for Type0 /* provide concrete impls */ // In C++ this would be inheritance for Type0
struct Type1 ...
impl State for Type1 /* provide concrete impls */ // In C++ this would be inheritance for Type1
// ... etc.
I was using this library and everything was working fine. But now there are a few types that have to do
some specific work which is beyond what's there in the State
trait above. So i gradually seem
to be running into the "Expressions Problem" in design. I don't control the library providing
the trait and the event-loop and even if i did i wouldn't have added 2 or 3 extra functions
there as it does not feel right since it's going to be used only for some concrete types and
that too occassionally.
What i have additionally is a Map in the user code like HashMap<u32, SomeDetail>
which
corresponds to the map in the event-loop thread stack above. So if i need to perform a special
operation on one of the types i can get the u32
value for the state (by analysing the SomeDetail
or whatever), get the state from the map in the event-loop and downcast it to the type to call
one of the special functions.
At this point in C++ i would probably have used static_cast<>
as I'm sure what type it is
(unless there's something wrong in the bookeeping of the id's or it's allocation which would be
a logic error in the program). In Rust i'm forced to use downcast_mut
(dynamic_cast
in C++),
which I'm OK with (so far I've never got any runtime error from it, showing that the logic is
sound and static_cast
were it available in safe-rust would have worked too).
Now my question is that I read that casting is bad design etc. So I was thinking what could I
have done differently here. One idea was to store the weak (or strong if we don't care) references in the
map that i have in my user code. So while the event loop uses the map it has to fire some
function for the State
, I would use my map to get the concrete type out whenever I want it
and invoke function on it. However since my code is outside the eventloop thread I would have
to slap a Mutex on the states, which is useless in 99% of the time as most of the time it's the
eventloop invoking it and types doing what they are coded to do.
- Should i keep a few maps of (reference to) concrete types the
special functionality on which i want to call occasionally and
slap a mutex there ? - Just do a dynamic_cast in those cases and this is justifiable ?
- Eventloop should have been templatised giving an opportunity for the user to store some state in the eventloop thread stack and deal with it. In this case I would store a few of my maps of
<u32, ConcreteTypeReferences>
so that I can post the request to the event-loop in rare cases I want to interact with the concrete-types and they can continue living without mutex or atomic-referece-counted objects (in Rust Rc is non-atomic-ref-counted smart-ptr, I don't know if there's an equivalent in C++)
The last option and also partly the 1st one requires I have access to that code - so more of a wish-list but just wanting to know what would have been the suggestion if that were the case. In absence of that (2) dynamic_cast
seems the only viable solution ?
design-patterns rust
1
I feel there is a lot more to this question than what you've put here. What you want is for someone to review your whole program/library and make a suggestion, but from just this snippet and your description, we'd just be guessing. If you can post the whole program, and your question is otherwise on-topic for Code Review, perhaps you would get better results there.
– trentcl
Nov 13 '18 at 12:33
1
For what it's worth, you can do the equivalent ofstatic_cast
in Rust, you just have to useunsafe
because you're asserting a type relationship the compiler can't verify. The conversion would look like&mut *(state as *mut _ as *mut Type0)
. The firstas
converts the reference to a raw pointer; the secondas
just discards the vtable pointer. Here's a more complete example
– trentcl
Nov 13 '18 at 12:58
Ah sorry, i did say "and static_cast were it available in safe-rust would have worked too" - but perhaps didn't make it more explicit. What i meant was that I know what the concrete type is due to some other meta-data elsewhere (like theu32
id here) so i would have normally gone forstatic_cast
. So I'm not really usingdynamic_cast
here to find out if it's really the type i want and then do something with it - rather i know what it is and just want to get the concrete type out of it. Is casting bad even in such cases ?
– ustulation
Nov 13 '18 at 13:34
1
Agree on putting up more code. I'll do that in code-review part of stackexchange if it helps. It might take me a while to trim out to minimal compilable example to explain my scenario.
– ustulation
Nov 13 '18 at 13:35
1
I don't think downcasting is bad; that's too simplistic. Rather, downcasting should offer enough mental friction to make you think, "Hmm, I wonder if there's a better way to build this." You definitely shouldn't turn a simple, performant solution into a complicated, sluggish one, just to avoid downcasting! But you should think about why you believe downcasting is necessary and whether it would make sense to eliminate it by refactoring.
– trentcl
Nov 13 '18 at 14:47
add a comment |
// ===== library code: =====
trait Sate // Or in C++ imagine this is a class containing only pure virtuals.
fn ready(&mut self, ..);
fn terminate(&mut self, ..);
fn timeout(&mut self, .. );
fn ....; // a few more functions
fn as_any(&mut self) -> &mut Any; // for downcasting in Rust; not necessary in C++
states: HashMap<u32, Rc<RefCell<State>>>; // Or in C++ just a map of numbers to shared-ptr of State
fn event_loop_on_some_trigger(trigger_for: u32, trigger: Blah)
let state = states[trigger_for];
if trigger == for_timeout state.borrow_mut().timeout(...)
else if trigger = for_readiness state.borrow_mut().timeout(...)
...
//==== User Code: ====
struct Type0 ...
impl State for Type0 /* provide concrete impls */ // In C++ this would be inheritance for Type0
struct Type1 ...
impl State for Type1 /* provide concrete impls */ // In C++ this would be inheritance for Type1
// ... etc.
I was using this library and everything was working fine. But now there are a few types that have to do
some specific work which is beyond what's there in the State
trait above. So i gradually seem
to be running into the "Expressions Problem" in design. I don't control the library providing
the trait and the event-loop and even if i did i wouldn't have added 2 or 3 extra functions
there as it does not feel right since it's going to be used only for some concrete types and
that too occassionally.
What i have additionally is a Map in the user code like HashMap<u32, SomeDetail>
which
corresponds to the map in the event-loop thread stack above. So if i need to perform a special
operation on one of the types i can get the u32
value for the state (by analysing the SomeDetail
or whatever), get the state from the map in the event-loop and downcast it to the type to call
one of the special functions.
At this point in C++ i would probably have used static_cast<>
as I'm sure what type it is
(unless there's something wrong in the bookeeping of the id's or it's allocation which would be
a logic error in the program). In Rust i'm forced to use downcast_mut
(dynamic_cast
in C++),
which I'm OK with (so far I've never got any runtime error from it, showing that the logic is
sound and static_cast
were it available in safe-rust would have worked too).
Now my question is that I read that casting is bad design etc. So I was thinking what could I
have done differently here. One idea was to store the weak (or strong if we don't care) references in the
map that i have in my user code. So while the event loop uses the map it has to fire some
function for the State
, I would use my map to get the concrete type out whenever I want it
and invoke function on it. However since my code is outside the eventloop thread I would have
to slap a Mutex on the states, which is useless in 99% of the time as most of the time it's the
eventloop invoking it and types doing what they are coded to do.
- Should i keep a few maps of (reference to) concrete types the
special functionality on which i want to call occasionally and
slap a mutex there ? - Just do a dynamic_cast in those cases and this is justifiable ?
- Eventloop should have been templatised giving an opportunity for the user to store some state in the eventloop thread stack and deal with it. In this case I would store a few of my maps of
<u32, ConcreteTypeReferences>
so that I can post the request to the event-loop in rare cases I want to interact with the concrete-types and they can continue living without mutex or atomic-referece-counted objects (in Rust Rc is non-atomic-ref-counted smart-ptr, I don't know if there's an equivalent in C++)
The last option and also partly the 1st one requires I have access to that code - so more of a wish-list but just wanting to know what would have been the suggestion if that were the case. In absence of that (2) dynamic_cast
seems the only viable solution ?
design-patterns rust
// ===== library code: =====
trait Sate // Or in C++ imagine this is a class containing only pure virtuals.
fn ready(&mut self, ..);
fn terminate(&mut self, ..);
fn timeout(&mut self, .. );
fn ....; // a few more functions
fn as_any(&mut self) -> &mut Any; // for downcasting in Rust; not necessary in C++
states: HashMap<u32, Rc<RefCell<State>>>; // Or in C++ just a map of numbers to shared-ptr of State
fn event_loop_on_some_trigger(trigger_for: u32, trigger: Blah)
let state = states[trigger_for];
if trigger == for_timeout state.borrow_mut().timeout(...)
else if trigger = for_readiness state.borrow_mut().timeout(...)
...
//==== User Code: ====
struct Type0 ...
impl State for Type0 /* provide concrete impls */ // In C++ this would be inheritance for Type0
struct Type1 ...
impl State for Type1 /* provide concrete impls */ // In C++ this would be inheritance for Type1
// ... etc.
I was using this library and everything was working fine. But now there are a few types that have to do
some specific work which is beyond what's there in the State
trait above. So i gradually seem
to be running into the "Expressions Problem" in design. I don't control the library providing
the trait and the event-loop and even if i did i wouldn't have added 2 or 3 extra functions
there as it does not feel right since it's going to be used only for some concrete types and
that too occassionally.
What i have additionally is a Map in the user code like HashMap<u32, SomeDetail>
which
corresponds to the map in the event-loop thread stack above. So if i need to perform a special
operation on one of the types i can get the u32
value for the state (by analysing the SomeDetail
or whatever), get the state from the map in the event-loop and downcast it to the type to call
one of the special functions.
At this point in C++ i would probably have used static_cast<>
as I'm sure what type it is
(unless there's something wrong in the bookeeping of the id's or it's allocation which would be
a logic error in the program). In Rust i'm forced to use downcast_mut
(dynamic_cast
in C++),
which I'm OK with (so far I've never got any runtime error from it, showing that the logic is
sound and static_cast
were it available in safe-rust would have worked too).
Now my question is that I read that casting is bad design etc. So I was thinking what could I
have done differently here. One idea was to store the weak (or strong if we don't care) references in the
map that i have in my user code. So while the event loop uses the map it has to fire some
function for the State
, I would use my map to get the concrete type out whenever I want it
and invoke function on it. However since my code is outside the eventloop thread I would have
to slap a Mutex on the states, which is useless in 99% of the time as most of the time it's the
eventloop invoking it and types doing what they are coded to do.
- Should i keep a few maps of (reference to) concrete types the
special functionality on which i want to call occasionally and
slap a mutex there ? - Just do a dynamic_cast in those cases and this is justifiable ?
- Eventloop should have been templatised giving an opportunity for the user to store some state in the eventloop thread stack and deal with it. In this case I would store a few of my maps of
<u32, ConcreteTypeReferences>
so that I can post the request to the event-loop in rare cases I want to interact with the concrete-types and they can continue living without mutex or atomic-referece-counted objects (in Rust Rc is non-atomic-ref-counted smart-ptr, I don't know if there's an equivalent in C++)
The last option and also partly the 1st one requires I have access to that code - so more of a wish-list but just wanting to know what would have been the suggestion if that were the case. In absence of that (2) dynamic_cast
seems the only viable solution ?
design-patterns rust
design-patterns rust
edited Nov 12 '18 at 18:18
asked Nov 12 '18 at 18:13
ustulation
1,3981031
1,3981031
1
I feel there is a lot more to this question than what you've put here. What you want is for someone to review your whole program/library and make a suggestion, but from just this snippet and your description, we'd just be guessing. If you can post the whole program, and your question is otherwise on-topic for Code Review, perhaps you would get better results there.
– trentcl
Nov 13 '18 at 12:33
1
For what it's worth, you can do the equivalent ofstatic_cast
in Rust, you just have to useunsafe
because you're asserting a type relationship the compiler can't verify. The conversion would look like&mut *(state as *mut _ as *mut Type0)
. The firstas
converts the reference to a raw pointer; the secondas
just discards the vtable pointer. Here's a more complete example
– trentcl
Nov 13 '18 at 12:58
Ah sorry, i did say "and static_cast were it available in safe-rust would have worked too" - but perhaps didn't make it more explicit. What i meant was that I know what the concrete type is due to some other meta-data elsewhere (like theu32
id here) so i would have normally gone forstatic_cast
. So I'm not really usingdynamic_cast
here to find out if it's really the type i want and then do something with it - rather i know what it is and just want to get the concrete type out of it. Is casting bad even in such cases ?
– ustulation
Nov 13 '18 at 13:34
1
Agree on putting up more code. I'll do that in code-review part of stackexchange if it helps. It might take me a while to trim out to minimal compilable example to explain my scenario.
– ustulation
Nov 13 '18 at 13:35
1
I don't think downcasting is bad; that's too simplistic. Rather, downcasting should offer enough mental friction to make you think, "Hmm, I wonder if there's a better way to build this." You definitely shouldn't turn a simple, performant solution into a complicated, sluggish one, just to avoid downcasting! But you should think about why you believe downcasting is necessary and whether it would make sense to eliminate it by refactoring.
– trentcl
Nov 13 '18 at 14:47
add a comment |
1
I feel there is a lot more to this question than what you've put here. What you want is for someone to review your whole program/library and make a suggestion, but from just this snippet and your description, we'd just be guessing. If you can post the whole program, and your question is otherwise on-topic for Code Review, perhaps you would get better results there.
– trentcl
Nov 13 '18 at 12:33
1
For what it's worth, you can do the equivalent ofstatic_cast
in Rust, you just have to useunsafe
because you're asserting a type relationship the compiler can't verify. The conversion would look like&mut *(state as *mut _ as *mut Type0)
. The firstas
converts the reference to a raw pointer; the secondas
just discards the vtable pointer. Here's a more complete example
– trentcl
Nov 13 '18 at 12:58
Ah sorry, i did say "and static_cast were it available in safe-rust would have worked too" - but perhaps didn't make it more explicit. What i meant was that I know what the concrete type is due to some other meta-data elsewhere (like theu32
id here) so i would have normally gone forstatic_cast
. So I'm not really usingdynamic_cast
here to find out if it's really the type i want and then do something with it - rather i know what it is and just want to get the concrete type out of it. Is casting bad even in such cases ?
– ustulation
Nov 13 '18 at 13:34
1
Agree on putting up more code. I'll do that in code-review part of stackexchange if it helps. It might take me a while to trim out to minimal compilable example to explain my scenario.
– ustulation
Nov 13 '18 at 13:35
1
I don't think downcasting is bad; that's too simplistic. Rather, downcasting should offer enough mental friction to make you think, "Hmm, I wonder if there's a better way to build this." You definitely shouldn't turn a simple, performant solution into a complicated, sluggish one, just to avoid downcasting! But you should think about why you believe downcasting is necessary and whether it would make sense to eliminate it by refactoring.
– trentcl
Nov 13 '18 at 14:47
1
1
I feel there is a lot more to this question than what you've put here. What you want is for someone to review your whole program/library and make a suggestion, but from just this snippet and your description, we'd just be guessing. If you can post the whole program, and your question is otherwise on-topic for Code Review, perhaps you would get better results there.
– trentcl
Nov 13 '18 at 12:33
I feel there is a lot more to this question than what you've put here. What you want is for someone to review your whole program/library and make a suggestion, but from just this snippet and your description, we'd just be guessing. If you can post the whole program, and your question is otherwise on-topic for Code Review, perhaps you would get better results there.
– trentcl
Nov 13 '18 at 12:33
1
1
For what it's worth, you can do the equivalent of
static_cast
in Rust, you just have to use unsafe
because you're asserting a type relationship the compiler can't verify. The conversion would look like &mut *(state as *mut _ as *mut Type0)
. The first as
converts the reference to a raw pointer; the second as
just discards the vtable pointer. Here's a more complete example– trentcl
Nov 13 '18 at 12:58
For what it's worth, you can do the equivalent of
static_cast
in Rust, you just have to use unsafe
because you're asserting a type relationship the compiler can't verify. The conversion would look like &mut *(state as *mut _ as *mut Type0)
. The first as
converts the reference to a raw pointer; the second as
just discards the vtable pointer. Here's a more complete example– trentcl
Nov 13 '18 at 12:58
Ah sorry, i did say "and static_cast were it available in safe-rust would have worked too" - but perhaps didn't make it more explicit. What i meant was that I know what the concrete type is due to some other meta-data elsewhere (like the
u32
id here) so i would have normally gone for static_cast
. So I'm not really using dynamic_cast
here to find out if it's really the type i want and then do something with it - rather i know what it is and just want to get the concrete type out of it. Is casting bad even in such cases ?– ustulation
Nov 13 '18 at 13:34
Ah sorry, i did say "and static_cast were it available in safe-rust would have worked too" - but perhaps didn't make it more explicit. What i meant was that I know what the concrete type is due to some other meta-data elsewhere (like the
u32
id here) so i would have normally gone for static_cast
. So I'm not really using dynamic_cast
here to find out if it's really the type i want and then do something with it - rather i know what it is and just want to get the concrete type out of it. Is casting bad even in such cases ?– ustulation
Nov 13 '18 at 13:34
1
1
Agree on putting up more code. I'll do that in code-review part of stackexchange if it helps. It might take me a while to trim out to minimal compilable example to explain my scenario.
– ustulation
Nov 13 '18 at 13:35
Agree on putting up more code. I'll do that in code-review part of stackexchange if it helps. It might take me a while to trim out to minimal compilable example to explain my scenario.
– ustulation
Nov 13 '18 at 13:35
1
1
I don't think downcasting is bad; that's too simplistic. Rather, downcasting should offer enough mental friction to make you think, "Hmm, I wonder if there's a better way to build this." You definitely shouldn't turn a simple, performant solution into a complicated, sluggish one, just to avoid downcasting! But you should think about why you believe downcasting is necessary and whether it would make sense to eliminate it by refactoring.
– trentcl
Nov 13 '18 at 14:47
I don't think downcasting is bad; that's too simplistic. Rather, downcasting should offer enough mental friction to make you think, "Hmm, I wonder if there's a better way to build this." You definitely shouldn't turn a simple, performant solution into a complicated, sluggish one, just to avoid downcasting! But you should think about why you believe downcasting is necessary and whether it would make sense to eliminate it by refactoring.
– trentcl
Nov 13 '18 at 14:47
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53267844%2fis-it-necessary-to-add-code-to-avoid-casting-when-interface-alone-is-no-longer-s%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53267844%2fis-it-necessary-to-add-code-to-avoid-casting-when-interface-alone-is-no-longer-s%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I feel there is a lot more to this question than what you've put here. What you want is for someone to review your whole program/library and make a suggestion, but from just this snippet and your description, we'd just be guessing. If you can post the whole program, and your question is otherwise on-topic for Code Review, perhaps you would get better results there.
– trentcl
Nov 13 '18 at 12:33
1
For what it's worth, you can do the equivalent of
static_cast
in Rust, you just have to useunsafe
because you're asserting a type relationship the compiler can't verify. The conversion would look like&mut *(state as *mut _ as *mut Type0)
. The firstas
converts the reference to a raw pointer; the secondas
just discards the vtable pointer. Here's a more complete example– trentcl
Nov 13 '18 at 12:58
Ah sorry, i did say "and static_cast were it available in safe-rust would have worked too" - but perhaps didn't make it more explicit. What i meant was that I know what the concrete type is due to some other meta-data elsewhere (like the
u32
id here) so i would have normally gone forstatic_cast
. So I'm not really usingdynamic_cast
here to find out if it's really the type i want and then do something with it - rather i know what it is and just want to get the concrete type out of it. Is casting bad even in such cases ?– ustulation
Nov 13 '18 at 13:34
1
Agree on putting up more code. I'll do that in code-review part of stackexchange if it helps. It might take me a while to trim out to minimal compilable example to explain my scenario.
– ustulation
Nov 13 '18 at 13:35
1
I don't think downcasting is bad; that's too simplistic. Rather, downcasting should offer enough mental friction to make you think, "Hmm, I wonder if there's a better way to build this." You definitely shouldn't turn a simple, performant solution into a complicated, sluggish one, just to avoid downcasting! But you should think about why you believe downcasting is necessary and whether it would make sense to eliminate it by refactoring.
– trentcl
Nov 13 '18 at 14:47