Trabalhando com WebAssembly e Go: técnicas avançadas de integração

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Trabalhando com WebAssembly e Go: nível avançado



O WebAssembly (WASM) abre novos horizontes para o desenvolvimento web, permitindo executar código de alto desempenho escrito em linguagens diferentes do JavaScript. Go (Golang) com seu compilador para WASM e modelo simples de concorrência é um excelente candidato para criar módulos web complexos. Neste artigo, exploraremos técnicas avançadas de integração de Go e WebAssembly: trabalho com memória, transferência de estruturas de dados complexas, comunicação bidirecional com JavaScript e otimização de desempenho.



1. Transferência de estruturas de dados complexas entre Go e JavaScript



A transferência básica de números e strings via syscall/js é simples, mas para aplicações reais isso não é suficiente. A abordagem avançada envolve a serialização de estruturas complexas (slices, maps, tipos personalizados) em JSON ou formato binário.



Serialização via JSON

O método mais simples e universal é usar encoding/json. Você exporta uma função que recebe uma string JSON, desserializa-a em uma estrutura Go, processa e retorna o resultado de volta como JSON.



// main.gopackage main

import ( "encoding/json" "syscall/js")

type InputData struct { Name string `json:"name"` Value float64 `json:"value"`}

type OutputData struct { Greeting string `json:"greeting"` Square float64 `json:"square"`}

func processData(this js.Value, args []js.Value) interface{} { if len(args) < 1 { return "Error: expected JSON string" } inputJSON := args[0].String()

var input InputData if err := json.Unmarshal([]byte(inputJSON), &input); err != nil { return "Error: " + err.Error() }

output := OutputData{ Greeting: "Hello, " + input.Name, Square: input.Value * input.Value, }

resultJSON, _ := json.Marshal(output) return string(resultJSON)}

func main() { c := make(chan struct{}, 0) js.Global().Set("processData", js.FuncOf(processData)) <-c}


Trabalho direto com memória (protocolo binário)

Para desempenho máximo, você pode transferir dados através da memória linear do WASM. Você exporta funções para escrever/ler da memória e passa ponteiros (como números inteiros) para o JavaScript. Este método é mais complexo, mas evita a sobrecarga de análise de JSON.



// Exportação de função para escrever na memória//go:wasmexport allocateMemoryfunc allocateMemory(size int) uintptr {    // Usa C.malloc ou seu próprio alocador    // Retorna o ponteiro}

//go:wasmexport getMemoryBufferfunc getMemoryBuffer() uintptr { // Retorna o início do buffer}


No JavaScript, você usa WebAssembly.Memory e Uint8Array para ler/escrever nos endereços obtidos.



2. Chamando JavaScript a partir de Go e manipulando o DOM



O pacote syscall/js permite chamar qualquer função JavaScript e manipular o DOM. O nível avançado envolve a criação de interfaces reativas e tratamento de eventos.



Criação e atualização de elementos do DOM

func appendDiv(this js.Value, args []js.Value) interface{} {    document := js.Global().Get("document")    body := document.Get("body")

newDiv := document.Call("createElement", "div") newDiv.Set("innerHTML", "<h2>Hello from Go WASM!</h2>") newDiv.Get("style").Set("color", "blue") body.Call("appendChild", newDiv) return nil}

func main() { js.Global().Set("appendDiv", js.FuncOf(appendDiv)) select {}}


Tratamento de eventos no lado do Go

func setupClickHandler(this js.Value, args []js.Value) interface{} {    document := js.Global().Get("document")    button := document.Call("getElementById", "myButton")

clickCallback := js.FuncOf(func(this js.Value, args []js

Blogs

Book Recommendations