Return how many of them contain an even number of digits (in given array/vector)

what's better way to implement constraints and code style and structure.

A simple solution would look like this:

pub fn find_numbers(nums: Vec<i32>) -> i32 {
    nums.iter().filter(|n| n.to_string().len() % 2 == 0).count() as i32

If you want to add the assertions back in, you can do it like this:

pub fn find_numbers(nums: Vec<i32>) -> i32 {
    assert!(nums.len() <= 500);
    nums.into_iter().filter(|n| {
        assert!(*n < 100000);
        n.to_string().len() % 2 == 0
    }).count() as i32

You can also make this faster by computing the number of digits using division, instead of converting to a string:

use std::iter::successors;

fn len(n: i32) -> i32 {
    successors(Some(n), |&i| (i >= 10).then(|| i / 10)).count() as i32

pub fn find_numbers(nums: Vec<i32>) -> i32 {
    nums.into_iter().filter(|n| len(*n) % 2 == 0).count() as i32

Here's a couple over-optimized versions. That's the mindset I go into when I see code problems like this, I guess. Given the constraints, you don't really need this and might as well use @mbrubeck's simpler versions.

A general note about the constraints though: when code competitions or problem sets like this tell you the constraints, they are generally telling you what you can assume about the inputs (so you know what cases you have to handle), and not rules that you have to enforce. As in @mbrubeck's main examples, you don't actually need most (arguably, all) of the assertions in my versions. Since you asked about the constraints specifically, I left them in.