0

Is there a better way to use i and j for-in variables that avoids the use of std::convert::TryInto and return vec![i.try_into().unwrap(),j.try_into().unwrap()]; for dealing with the usize and i32 conversion problem between what is expected as a result and the actual value type of these variables?

The use of the module and the try_into() and unwrap() functions was because of the compiler error suggestion. But I want to know if there is another way to cast or convert numeric values.

use std::convert::TryInto;

impl Solution {
    pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
       let mut current = 0;
       for i in 0..nums.len() - 1 {
           for j in 1..nums.len(){
               if j != i {
                   current = nums[i] + nums[j];
                   if current == target {
                       return vec![i.try_into().unwrap(),j.try_into().unwrap()];
                   }
               }
           }
       }
       vec![] 
    }
}
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • Why return `Vec` instead of `Vec`? – PitaJ Nov 07 '22 at 19:23
  • This is a solution from a TwoSum problem of LeetCode https://leetcode.com/problems/two-sum/description/ and that is the function signature. – Alex Alvarez Gárciga Nov 07 '22 at 19:35
  • 1
    Personally, that function signature is just wrong. You should pretty much always use `usize` for indices. Seems like they're using `i32` because it's the equivalent of `int`, but that's pretty wrong in C++ too (should be `size_t`). – PitaJ Nov 07 '22 at 19:48
  • 1
    But yeah, absent that, `.try_into().unwrap()` is the most idiomatic way. – PitaJ Nov 07 '22 at 19:50
  • 1
    "But I want to know if there is another way to cast or convert numeric values." - yes, you can use `i as usize` and `j as usize` respectively, which is more readable and, I'd argue, more idiomatic. – user4815162342 Nov 07 '22 at 20:00
  • 2
    @user4815162342 Please don't encourage people to switch from `try_into()` to `as`, particularly not beginners. There's a reason the compiler's help messages don't suggest using `as`. I'd argue that `as` is *not* idiomatic: it's short, yes, but its brevity is a footgun. It silently corrupts out-of-range values, which is quite un-Rust-like. What's actually idiomatic is using `into()` for lossless conversions and `try_into().unwrap()` for lossy ones. – John Kugelman Nov 07 '22 at 20:45
  • 1
    I wish Rust had some `wrapping_into()` methods or similar to replace `as`. – Chayim Friedman Nov 07 '22 at 21:21

1 Answers1

1

There is the i as i32 syntax, but that can cause silent overflow if nums.len() > i32::MAX

where i32::MAX = 2_147_483_647 https://doc.rust-lang.org/std/i32/constant.MAX.html

impl Solution {
    pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
        nums.iter()
            .enumerate()
            .find_map(|(i, &x)| {
                nums.iter()
                    .enumerate()
                    .find(|(j, &y)| *j != i && (x + y) == target)
                    .map(|(j, _)| vec![i as i32, j as i32])
            })
            .unwrap_or_default()
    }
}
Oussama Gammoudi
  • 685
  • 7
  • 13
  • 1
    I fear that putting `as` in an answer will tempt people to use it. Panicking is good, better than silent data corruption; the problem with `as` is that it *doesn't* panic. – John Kugelman Nov 07 '22 at 20:40