dongzhan7253 2017-05-11 18:21
浏览 25
已采纳

我无法在追加到数组后修改项目

I'm developing a multiplayer api for Unity Engine. I have Room and RoomManager struct. When I want create room, I set room name, id (all of variable), after that I append this new room to allRoom array in RoomManager struct. After that when I modified to room variable, I can't change any variable. I dont know why ?

Here is my structs and methods :

RoomManager struct

type RoomManager struct {
   allRooms    []Room
   roomCounter int
}

Room struct

type Room struct {
   tag               string
   name              string
   password          string
   id                int
   cappacity         int
   maxVariableCount  int
   userList          []User
   roomVariables     []RoomVariable
   extensionHandlers []ExtensionRequest
   InitializeMethod  roomInitializeFunc
}

Room Create Method

func (roomManager *RoomManager) CreateRoom(settings RoomSettings, arwServer *ARWServer) *Room {

   var newRoom Room
   newRoom.InitializeMethod = settings.InitializeMethod

   newRoom.name = settings.name
   newRoom.password = settings.password
   newRoom.tag = settings.tag
   newRoom.cappacity = settings.cappacity
   newRoom.maxVariableCount = settings.maxRoomVariableCount

   newRoom.id = roomManager.roomCounter
   roomManager.roomCounter++

   newRoom.userList = make([]User, 0, newRoom.cappacity)
   newRoom.roomVariables = make([]RoomVariable, 0, newRoom.maxVariableCount)

   if newRoom.InitializeMethod != nil {
     newRoom.InitializeMethod(arwServer, &newRoom)
   }

   roomManager.allRooms = append(roomManager.allRooms, newRoom)
   return &newRoom
}

Add User To Room

func (room *Room) AddUserToRoom(arwServer *ARWServer, u User) {
   room.userList = append(room.userList, u)

   var arwObj ARWObject

   arwObj.requestName = Join_Room
   arwObj.eventParams.PutString("RoomName", room.name)
   arwObj.eventParams.PutString("RoomTag", room.tag)
   arwObj.eventParams.PutInt("RoomId", room.id)
   arwObj.eventParams.PutInt("RoomCappacity", room.cappacity)

   usersData := ""
   for ii := 0; ii < len(room.userList); ii++ {
     if room.userList[ii].name != u.name {
       usersData += room.userList[ii].GetDataForOtherUser(u) + "''"
     }
   }

   usersData = strings.TrimRight(usersData, "''")

   arwObj.eventParams.PutString("Users", usersData)
   arwServer.SendRequestToUser(u, arwObj)

   var arwObjforTheOthers ARWObject
   arwObjforTheOthers.requestName = User_Enter_Room
   arwObjforTheOthers.eventParams.PutString("RoomName", room.name)
   arwObjforTheOthers.eventParams.PutString("userName", u.name)
   arwObjforTheOthers.eventParams.PutInt("userId", u.id)
   arwObjforTheOthers.eventParams.PutString("isMe", "false")

   room.SendRequestAllUserWithoutMe(*arwServer, arwObjforTheOthers, u)
   fmt.Println("User join Room - User Name : ", u.name+" Room : "+u.lastRoom.name)
}
  • 写回答

1条回答 默认 最新

  • dqu92800 2017-05-11 18:30
    关注

    Your issue is that your structs have non-pointer slices. In all of your structs define your slices as slices of pointers like so

    Rooms []*Room
    

    You also need to define your functions to take pointer values, like so

    func(room *Room) {}
    

    To elaborate. Go is pass-by-value. Anytime you pull something out of one of your original slices and pass it to one of your functions, it gets a copy. Using pointers modifies the actual value in the slice.

    See this example. https://play.golang.org/p/ZThHrP0pds

    package main
    
    import (
        "fmt"
    )
    
    type Thing struct {
        Name string
    }
    
    func main() {
        things := []Thing{}
        thing := Thing{"thing1"}
    
        // add to slice
        // note that this is a function call
        things = append(things, thing)
    
        // attempt to change
        thing.Name = "thing2"
        fmt.Println(things[0].Name) // prints thing1
        fmt.Println(thing.Name)     // prints thing2
    
        fmt.Println("------")
    
        // try again
        thing3 := things[0]
        thing3.Name = "thing3"
        // fail again
        fmt.Println(things[0].Name) // prints thing1
        fmt.Println(thing3.Name)     // prints thing3
    
        fmt.Println("------")
    
        // do this instead
        betterThings := []*Thing{} // slice of pointers
        betterThing := &Thing{"thing2"} // betterThing is of type *Thing
    
        // add to slice
        betterThings = append(betterThings, betterThing)
    
        // successfully change
        betterThing.Name = "thing2"
    
        fmt.Println(betterThings[0].Name) // prints thing2
        fmt.Println(betterThing.Name)     // prints thing2
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 求螺旋焊缝的图像处理
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误
  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了