ch13_反射reflection

本文深入探讨了Go语言中的反射机制,包括基本结构、匿名或嵌入字段的反射、通过反射修改元素值以及调用结构体方法的具体示例。通过实践代码展示了如何使用reflect包进行类型检查和操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

反射reflection

反射的基本结构

  • 要导入reflect
import (
    "fmt"
    "reflect"
)

type User struct {
    Id   int
    Name string
    Age  int
}

func (u User) Hello() {
    fmt.Println("Hello world.")
}
func Info(o interface{}) {
    t := reflect.TypeOf(o)
    //判断o是否为结构体
    if k := t.Kind(); k != reflect.Struct {
        fmt.Println("这不是个结构体")
        return
    }
    fmt.Println("Type:", t.Name())
    v := reflect.ValueOf(o)
    fmt.Println("Fields:")
    for i := 0; i < t.NumField(); i++ {
        f := t.Field(i)
        val := v.Field(i).Interface()
        fmt.Printf("%6s: %v %v\n", f.Name, f.Type, val) //对于interface{}, %v会打印实际类型的值
    }
    for i := 0; i < t.NumMethod(); i++ {
        m := t.Method(i)
        fmt.Printf("%6s: %v\n", m.Name, m.Type)
    }
}
func main() {
    u := User{1, "OK", 12}
    Info(u)
}

%v the value in a default format
when printing structs, the plus flag (%+v) adds field names
%#v a Go-syntax representation of the value
%T a Go-syntax representation of the type of the value

反射匿名或嵌入字段

  • 通过查看其类型中Anonymous的真假判断是否为匿名字段
type User struct {
    Id   int
    Name string
    Age  int
}
type Manager struct {
    User
    title string
}

func (u User) Hello() {
    fmt.Println("Hello world.")
}

func main() {
    m := Manager{User: User{1, "OK", 13}, title: "233"}
    t := reflect.TypeOf(m)
    //通过Anonymous字段判断是否为匿名字段
    fmt.Printf("%#v\n", t.Field(0))
    fmt.Printf("%#v\n", t.Field(1))
    //取第0号元素里的第0号元素,即User字段里的Id
    fmt.Printf("%#v\n", t.FieldByIndex([]int{0, 0}))
}

输出结果

reflect.StructField{Name:“User”, PkgPath:"", Type:(*reflect.rtype)(0x4c9a00), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:true}
reflect.StructField{Name:“title”, PkgPath:“main”, Type:(*reflect.rtype)(0x4b6380), Tag:"", Offset:0x20, Index:[]int{1}, Anonymous:false}
reflect.StructField{Name:“Id”, PkgPath:"", Type:(*reflect.rtype)(0x4b5bc0), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:false}

通过反射修改元素的值

  • 要使用元素的指针
    x := 123
    v := reflect.ValueOf(&x)
    v.Elem().SetInt(999)
    fmt.Println(x)
  • 修改结构体元素示例
type User struct {
    Id   int
    Name string
    Age  int
}

func Set(o interface{}) {
    v := reflect.ValueOf(o)
    //判断v是否为指针
    if v.Kind() != reflect.Ptr {
        fmt.Println("不是指针,无法修改")
        return
    }
    //判断v所指向的值是否可以被修改
    if v.Elem().CanSet() == false {
        fmt.Println("属性为不可修改")
        return
    }
    //取出v的值
    v = v.Elem()
    f := v.FieldByName("Name")
    if f.IsValid() == false {
        fmt.Println("没有找到")
        return
    }
    switch f.Kind() {
    case reflect.Int:
        f.SetInt(1)
    case reflect.String:
        f.SetString("ByeBye")
    }
}
func main() {
    u := User{Id: 55, Name: "Hello", Age: 13}
    Set(&u)
    fmt.Println(u)
}
  • 调用结构体方法示例
type User struct {
    Id   int
    Name string
    Age  int
}

func (u User) Hello(name string) {
    fmt.Println("Hello", name, ", my name is", u.Name)
}
func main() {
    u := User{Id: 55, Name: "Alice", Age: 13}
    v := reflect.ValueOf(u)
    mv := v.MethodByName("Hello")
    args := []reflect.Value{reflect.ValueOf("Bob")}
    mv.Call(args)
}
using ch.sycoforge.Types; using UnityEngine; using UnityEngine.Profiling; using static UnityEditor.ShaderData; Shader "Custom/WaterShaderWithDepth" { Properties { _Color ("Shallow Water Color", Color) = (0.2, 0.6, 1, 0.8) _DepthColor ("Deep Water Color", Color) = (0.1, 0.3, 0.5, 1) _WaveSpeed ("Wave Speed", Range(0, 5)) = 1.0 _WaveHeight ("Wave Height", Range(0, 1)) = 0.2 _WaveFrequency ("Wave Frequency", Range(0, 10)) = 2.0 _NormalMap ("Normal Map", 2D) = "bump" {} _NormalScale("Normal Scale", Range(0, 2)) = 0.5 _ReflectionCube("Reflection Cubemap", Cube) = "" { } _ReflectionIntensity("Reflection Intensity", Range(0, 1)) = 0.7 _Glossiness("Smoothness", Range(0, 1)) = 0.9 _DepthMaxDistance("Depth Max Distance", Float) = 10.0 _DepthFactor("Depth Factor", Range(0, 5)) = 1.0 _FoamColor("Foam Color", Color) = (1, 1, 1, 1) _FoamThreshold("Foam Threshold", Range(0, 1)) = 0.3 _FoamIntensity("Foam Intensity", Range(0, 1)) = 0.5 } SubShader { Tags { "RenderType"="Transparent" "Queue"="Transparent" } LOD 300 Blend SrcAlpha OneMinusSrcAlpha ZWrite Off CGPROGRAM #pragma surface surf Standard alpha:fade #pragma target 3.0 # include "UnityCG.cginc" struct Input { float2 uv_NormalMap; float3 worldPos; float3 worldRefl; float4 screenPos; INTERNAL_DATA }; fixed4 _Color; fixed4 _DepthColor; float _WaveSpeed; float _WaveHeight; float _WaveFrequency; sampler2D _NormalMap; float _NormalScale; samplerCUBE _ReflectionCube; float _ReflectionIntensity; float _Glossiness; float _DepthMaxDistance; float _DepthFactor; fixed4 _FoamColor; float _FoamThreshold; float _FoamIntensity; sampler2D _CameraDepthTexture; // 深度纹理 void surf(Input IN, inout SurfaceOutputStandard o) { // 波浪动画 float wave1 = sin(_Time.y * _WaveSpeed + IN.worldPos.x * _WaveFrequency) * _WaveHeight; float wave2 = sin(_Time.y * _WaveSpeed * 0.7 + IN.worldPos.z * _WaveFrequency * 1.3) * _WaveHeight * 0.7; float wave = wave1 + wave2; // 法线贴图 float2 normalUV = IN.uv_NormalMap; normalUV.x += _Time.x * 0.1; normalUV.y += _Time.x * 0.05; fixed3 normal1 = UnpackScaleNormal(tex2D(_NormalMap, normalUV), _NormalScale); fixed3 normal2 = UnpackScaleNormal(tex2D(_NormalMap, normalUV * 1.7 + float2(0.2, -0.3)), _NormalScale * 0.7); o.Normal = normalize(normal1 + normal2); // 菲涅尔效应 float3 viewDir = normalize(IN.worldPos - _WorldSpaceCameraPos); float fresnel = pow(1.0 - saturate(dot(o.Normal, viewDir)), 4); // 反射计算 float3 worldRefl = WorldReflectionVector(IN, o.Normal); fixed4 reflection = texCUBE(_ReflectionCube, worldRefl); // ================== 深度计算 ================== // 获取屏幕坐标和深度值 float2 screenUV = IN.screenPos.xy / IN.screenPos.w; #if UNITY_UV_STARTS_AT_TOP screenUV.y = 1 - screenUV.y; #endif // 采样场景深度 float sceneDepth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenUV)); // 计算水面深度 float waterSurfaceDepth = IN.screenPos.w; // 计算实际水深 float waterDepth = sceneDepth - waterSurfaceDepth; // 标准化水深 (0-1范围) float depthNormalized = saturate(waterDepth / _DepthMaxDistance); // 应用深度因子调整 float depthFactor = saturate(depthNormalized * _DepthFactor); // ================== 颜色混合 ================== // 基于水深混合浅水和深水颜色 fixed4 baseColor = lerp(_Color, _DepthColor, depthFactor); // 添加泡沫效果(岸边浅水区) float foam = 1 - saturate(depthFactor / _FoamThreshold); fixed4 foamColor = _FoamColor * foam * _FoamIntensity; baseColor.rgb += foamColor.rgb; // 混合反射 fixed4 waterColor = lerp(baseColor, reflection, fresnel * _ReflectionIntensity); // 应用波浪高度影响颜色 waterColor.rgb *= 1.0 - (abs(wave) * 0.2); o.Albedo = waterColor.rgb; o.Metallic = 0.0; o.Smoothness = _Glossiness; // 透明度基于水深调整(深水区更透明) o.Alpha = lerp(_Color.a, _DepthColor.a, depthFactor * 0.5); } ENDCG } FallBack "Transparent/Diffuse" }
07-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值