Me llego este mail y quería compartirlo:
Las empresas modernas eligen Oracle Cloud Infrastructure (OCI) |
En este ebook te contamos las razones |
Conoce cómo las empresas crean y ejecutan aplicaciones seguras y escalables gracias a la nube de Oracle. |
Me llego este mail y quería compartirlo:
Las empresas modernas eligen Oracle Cloud Infrastructure (OCI) |
En este ebook te contamos las razones |
Conoce cómo las empresas crean y ejecutan aplicaciones seguras y escalables gracias a la nube de Oracle. |
#[derive(Debug)]
struct Person {
name: String,
age: u8,
}
impl Person {
fn say_hello(&self) {
println!("Hello, my name is {}", self.name);
}
}
fn main() {
let peter = Person {
name: String::from("Peter"),
age: 27,
};
peter.say_hello();
}
El &self del post anterior indica que el método toma prestado el objeto de forma inmutable. Hay otros posibles receptores para un método:
Más allá de las variantes de self, también hay tipos de contenedores especiales que pueden ser tipos de receptores, como Box<Self>.
Estas restricciones siempre se juntan en Rust debido a las reglas del verificador prestado, y self no es una excepción. No es posible hacer referencia a una estructura desde múltiples ubicaciones y llamar a un método mutante (&mut self) en ella.
#[derive(Debug)]
struct Person {
name: String,
age: u8,
}
impl Person {
fn say_hello(&self) {
println!("Hello, my name is {}", self.name);
}
}
fn main() {
let peter = Person {
name: String::from("Peter"),
age: 27,
};
peter.say_hello();
}
Los métodos se llaman en una instancia de un tipo (como una estructura o enumeración), el primer parámetro representa la instancia como self.
Los desarrolladores pueden optar por utilizar métodos para aprovechar la sintaxis del receptor de métodos y ayudar a mantenerlos más organizados. Al utilizar métodos, podemos mantener todo el código de implementación en un lugar predecible.
self es un término abreviado y es de tipo &Person, por lo tanto podemos escribir esto como :
impl Person {
fn say_hello(self : &Person) {
println!("Hello, my name is {}", self.name);
}
}
Uno de los requerimientos no funcionales es que se pueda agregar una serie nueva fácilmente.
Vamos a desarrollar este juego en Rust:
Empecemos desarrollo de la serie, la serie tiene como responsabilidad generarse y si lo hacemos de esta manera podemos utilizar la potencia del polimorfismo, para que no quede acoplado la generación de la serie con el desarrollo del juego:
use rand::{thread_rng, Rng};
pub fn iniciar_secuencia() -> [u16;4] {
let semilla:u8 = thread_rng().gen_range(0..3);
match semilla {
0 => return generar_secuencia_par(),
1 => return generar_secuencia_inpar(),
_ => return generar_fibonacci()
}
}
//Esta función genera la serie y para eso utiliza diferentes funciones que generan diferentes tipos de secuencias :
fn generar_secuencia_par() -> [u16;4] {
let mut resultado:[u16;4] = [0; 4];
let semilla:u16 = thread_rng().gen_range(0..30);
for i in 0..4 {
resultado[i] = semilla * 2 + (i as u16) * 2;
}
resultado
}
fn generar_secuencia_inpar() -> [u16;4] {
let mut resultado:[u16;4] = [0; 4];
let semilla:u16 = thread_rng().gen_range(0..30);
for i in 0..4 {
resultado[i] = semilla * 2 + (i as u16) * 2 + 1;
}
resultado
}
fn generar_fibonacci() -> [u16;4] {
let mut _resultado:[u16;4] = [0; 4];
let semilla:u16 = thread_rng().gen_range(0..30);
for i in 0..4 {
if i < 2 {
_resultado[i] = semilla;
} else {
_resultado[i] = _resultado[i-1] + _resultado[i-2];
}
}
_resultado
}
Y listo!! ahora en el main tenemos que llamar a esta función y ver si esta bien el resultado:
use std::io;
use crate::serie::iniciar_secuencia;
mod serie;
fn main() {
let mut puntos = 0u8;
loop {
let serie:[u16;4] = iniciar_secuencia();
println!("Serie: ");
for i in 0..2 {
print!(" {} ", serie[i]);
}
println!("_____ {} ", serie[3]);
println!("Ingrese el valor faltante: ");
let mut input = String::new();
io::stdin().read_line(&mut input).expect("error: unable to read user input");
let x = input.trim().parse().expect("Error!! debe ser un numero.");
if serie[2].eq(&x) {
println!("Ganaste !! ");
puntos = puntos + 1;
} else {
println!("Perdiste !! ");
}
println!("Puntos : {} ", puntos);
println!("Desea continuar jugando? (y/n): ");
let mut continuar = String::new();
io::stdin().read_line(&mut continuar).expect("error: unable to read user input");
if continuar.trim().ne("y"){
return;
}
}
}
PRENSA GUGLER LAB 2023 | |||||
NOTICIAS ACTUALES | OFERTA ACADÉMICA | ||||
Se encuentran abiertas las inscripciones para el segundo cuatrimestre del año 2023, para todas las capacitaciones dictadas por el Laboratorio de Investigación Gugler. Podés asegurar tu lugar en el curso y comisión que desees !!!. Las clases inician:
Inscribirte: clic aquí Cursos, Horarios y comisiones: clic aquí.
| Dictamos nuestros cursos en la Facultad de Ciencia y Tecnología, perteneciente a la Universidad Autónoma de Entre Ríos. En nuestro portafolio de capacitación encontrarás: MODALIDAD PRESENCIAL
MODALIDAD DISTANCIA
| ||||
MÁS INFORMACIÓN | LABORATORIO DE INVESTIGACIÓN GUGLER | ||||
Si deseas comunicarte con nosotros, te recordamos que podes hacerlo a través de los siguientes portales, en los cuales encontrarás información sobre Gugler. TEL: (0343) - 4975066 Interno 119 Sitio Oficial: www.gugler.com.ar Campus: campusvirtual.gugler.com.ar Sistema de Gestión Cursos: sgc.gugler.com.ar Sistema de Gestión Cursos Móvil: Aquí Sistema de Documentación: sgd.gugler.com.ar Sistema de Validación: giua.gugler.com.ar |
| ||||
GUGLER PRESS | |||||
use std::any::type_name;
use std::mem::{align_of, size_of};
fn dbg_size<T>() {
println!("{}: size {} bytes, align: {} bytes",
type_name::<T>(), size_of::<T>(), align_of::<T>());
}
enum Foo {
A,
B,
}
fn main() {
dbg_size::<Foo>();
}
Internamente, Rust está utilizando un campo (discriminante) para realizar un seguimiento de la variante de enumeración.
Puede controlar el discriminante si es necesario (por ejemplo, para compatibilidad con C):
enum WebEvent {
PageLoad, // Variant without payload
KeyPress(char), // Tuple struct variant
Click { x: i64, y: i64 }, // Full struct variant
}
#[rustfmt::skip]
fn inspect(event: WebEvent) {
match event {
WebEvent::PageLoad => println!("page loaded"),
WebEvent::KeyPress(c) => println!("pressed '{c}'"),
WebEvent::Click { x, y } => println!("clicked at x={x}, y={y}"),
}
}
fn main() {
let load = WebEvent::PageLoad;
let press = WebEvent::KeyPress('x');
let click = WebEvent::Click { x: 20, y: 80 };
inspect(load);
inspect(press);
inspect(click);
}
fn generate_random_number() -> i32 {
// Implementation based on https://xkcd.com/221/
4 // Chosen by fair dice roll. Guaranteed to be random.
}
#[derive(Debug)]
enum CoinFlip {
Heads,
Tails,
}
fn flip_coin() -> CoinFlip {
let random_number = generate_random_number();
if random_number % 2 == 0 {
return CoinFlip::Heads;
} else {
return CoinFlip::Tails;
}
}
fn main() {
println!("You got: {:?}", flip_coin());
}
#[derive(Debug)]
struct Person {
name: String,
age: u8,
}
impl Person {
fn new(name: String, age: u8) -> Person {
Person { name, age }
}
}
fn main() {
let peter = Person::new(String::from("Peter"), 27);
println!("{peter:?}");
}
Podría escribirse usando Self como tipo, ya que es intercambiable con el nombre del tipo de estructura
#[derive(Debug)]
struct Person {
name: String,
age: u8,
}
impl Person {
fn new(name: String, age: u8) -> Self {
Self { name, age }
}
}
Podemos tambien definir los campos por defecto:
#[derive(Debug)]
struct Person {
name: String,
age: u8,
}
impl Default for Person {
fn default() -> Person {
Person {
name: "Bot".to_string(),
age: 0,
}
}
}
fn create_default() {
let tmp = Person {
..Person::default()
};
let tmp = Person {
name: "Sam".to_string(),
..Person::default()
};
}
struct Point(i32, i32);
fn main() {
let p = Point(17, 23);
println!("({}, {})", p.0, p.1);
}
Esto se usa a menudo para envoltorios de un solo campo:
struct PoundsOfForce(f64);
struct Newtons(f64);
fn compute_thruster_force() -> PoundsOfForce {
todo!("Ask a rocket scientist at NASA")
}
fn set_thruster_force(force: Newtons) {
// ...
}
fn main() {
let force = compute_thruster_force();
set_thruster_force(force);
}
struct Person {
name: String,
age: u8,
}
fn main() {
let mut peter = Person {
name: String::from("Peter"),
age: 27,
};
println!("{} is {} years old", peter.name, peter.age);
peter.age = 28;
println!("{} is {} years old", peter.name, peter.age);
let jackie = Person {
name: String::from("Jackie"),
..peter
};
println!("{} is {} years old", jackie.name, jackie.age);
}
Las estructuras funcionan como en C o C++.
Me llego este mail de google cloud y lo quiero compartir con ustedes:
|
Hola Emanuel, |
¿Conoces la frase “una imagen vale más que mil palabras”? Por eso, en vez de hablar sobre los beneficios de Looker, la solución de Google Cloud para el análisis de datos, te invitamos a conocer historias de éxito de sectores que están utilizando esta herramienta y han alcanzado excelentes resultados. |
En este material gratuito, te mostramos cómo empresas de diferentes áreas están impulsando sus estrategias de IE con las ventajas de Looker: |
|
También encontrarás resultados para inspirar a las personas a reflexionar sobre lo que pueden hacer los datos por las empresas. Accede al material y conoce todo lo que puede hacer Looker por tu empresa. |
|
Nos vemos en la nube, Equipo de Google Cloud |
|
#[derive(Debug)]
struct Highlight<'doc>(&'doc str);
fn erase(text: String) {
println!("Bye {text}!");
}
fn main() {
let text = String::from("The quick brown fox jumps over the lazy dog.");
let fox = Highlight(&text[4..19]);
let dog = Highlight(&text[35..43]);
// erase(text);
println!("{fox:?}");
println!("{dog:?}");
}
Si corremos esto:
$ cargo run
Compiling hello_cargo v0.1.0 (/home/emanuel/Projects/rust/hello_cargo)
warning: function `erase` is never used
--> src/main.rs:7:4
|
7 | fn erase(text: String) {
| ^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: `hello_cargo` (bin "hello_cargo") generated 1 warning
Finished dev [unoptimized + debuginfo] target(s) in 1.80s
Running `target/debug/hello_cargo`
Highlight("quick brown fox")
Highlight("lazy dog")
Pero si descomentamos esta linea // erase(text); y corremos:
$ cargo run
Compiling hello_cargo v0.1.0
error[E0505]: cannot move out of `text` because it is borrowed
--> src/main.rs:19:11
|
15 | let fox = Highlight(&text[4..19]);
| ---- borrow of `text` occurs here
...
19 | erase(text);
| ^^^^ move out of `text` occurs here
20 |
21 | println!("{fox:?}");
| --- borrow later used here
For more information about this error, try `rustc --explain E0505`.
error: could not compile `hello_cargo` due to previous error
Instalación de Paketo: La instalación de Paketo es sencilla y depende del lenguaje de programación que utilices. Sigue las instrucciones en la documentación oficial para instalar la CLI de Paketo y los paquetes necesarios.
Construcción de Imágenes: Para construir una imagen de contenedor con Paketo, dirígete al directorio de tu proyecto y utiliza el comando correspondiente al paquete de lenguaje que estás utilizando. Por ejemplo, para Java:
pack build my-java-app --builder paketobuildpacks/builder:base
#[derive(Debug)]
struct Point(i32, i32);
fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {
if p1.0 < p2.0 { p1 } else { p2 }
}
fn main() {
let p1: Point = Point(10, 10);
let p2: Point = Point(20, 20);
let p3: &Point = left_most(&p1, &p2);
println!("left-most point: {:?}", p3);
}
En el ejemplo anterior, intente lo siguiente:
Mueva la declaración de p2 y p3 a un nuevo ámbito ({ ... }), lo que da como resultado el siguiente código:
#[derive(Debug)]
struct Point(i32, i32);
fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {
if p1.0 < p2.0 { p1 } else { p2 }
}
fn main() {
let p1: Point = Point(10, 10);
let p3: &Point;
{
let p2: Point = Point(20, 20);
p3 = left_most(&p1, &p2);
}
println!("left-most point: {:?}", p3);
}
Esto no compila ya que p3 sobrevive a p2.
Restablezca el espacio de trabajo y cambie la firma de la función a fn left_most<'a, 'b>(p1: &'a Point, p2: &'a Point) -> &'b Point. Esto no se compilará porque la relación entre las vidas 'a y 'b no está clara.
Otra forma de explicarlo: